home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmiSoft / Util / Misc / Reportplus.lha / reportplus / source / f6.c < prev    next >
C/C++ Source or Header  |  2003-02-14  |  142KB  |  3,999 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <intuition/intuition.h>
  4. #include <intuition/gadgetclass.h>
  5. #include <libraries/iffparse.h>
  6. #include <dos/dos.h>
  7. #include <dos/datetime.h>
  8.  
  9. #include <clib/alib_protos.h>
  10. #include <clib/exec_protos.h>
  11. #include <clib/intuition_protos.h>
  12. #include <clib/iffparse_protos.h>
  13. #include <clib/dos_protos.h>
  14.  
  15. #define ALL_REACTION_CLASSES
  16. #define ALL_REACTION_MACROS
  17. #include <reaction/reaction.h>
  18.  
  19. #include <ctype.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "rp.h"
  23.  
  24. #define BYTESPERLINE 12 // how many bytes to print per line
  25. #define LABELLENGTH  25
  26.  
  27. #define ITEMS 255
  28. MODULE struct
  29. {   TEXT   name[5];
  30.     ULONG  bytes;
  31.     UBYTE* DataPtr;
  32. } contents[ITEMS + 1];
  33.  
  34. #define FORMS         92
  35.  
  36. #define CD             1
  37. #define OBSOLETE       2
  38. #define PRIVATE        4
  39. #define PROPOSAL       8
  40. #define RESERVED      16
  41. #define RKM           32
  42. #define STANDARD      64
  43. #define UNREGISTERED 128
  44.  
  45. #define IFFXCHARS     13
  46.  
  47. MODULE void iffquery(void);
  48. MODULE void PrintTopChunk(void);
  49. MODULE void readiff(void);
  50. MODULE void tellchunk(UWORD which);
  51. MODULE void chunkdesc(STRPTR desc, ABOOL isknown);
  52. MODULE void binarize(UBYTE data);
  53. MODULE void hexalize(UBYTE data);
  54. MODULE ULONG getulong(UBYTE* start);
  55. MODULE SLONG getslong(UBYTE* start);
  56. MODULE ULONG getuword(UBYTE* start);
  57. MODULE SLONG getsword(UBYTE* start);
  58. MODULE SLONG getsbyte(UBYTE* start);
  59. MODULE void writeiffgadgets(void);
  60. MODULE void dotextattr(UBYTE* offset);
  61. MODULE void docountry(UBYTE* offset);
  62. MODULE void label(STRPTR text);
  63. MODULE void dobool(UBYTE thebool);
  64. MODULE void snumcat(SLONG thenumber, ABOOL finished);
  65. MODULE void unumcat(ULONG thenumber, ABOOL finished);
  66. MODULE void interpret(ULONG tablenum, ULONG value);
  67.  
  68. #define TABLENUMS    54
  69. #define TABLEENTRIES 13
  70.  
  71. struct
  72. {   UBYTE  entries;
  73.     STRPTR tablestring[TABLEENTRIES + 1];
  74. } table[TABLENUMS + 1] =
  75. { { 2, // 0
  76.     "XON",  // HSHAKE_XON
  77.     "RTS",  // HSHAKE_RTS
  78.     "None"  // HSHAKE_NONE
  79.   },
  80.   { 2, // 1
  81.     "none",
  82.     "superscript",
  83.     "subscript"
  84.   },
  85.   { 2, // 2
  86.     "Unknown",
  87.     "No",
  88.     "Yes"
  89.   },
  90.   { 4, // 3
  91.     "None",
  92.     "Even",
  93.     "Odd",
  94.     "Mark",
  95.     "Space"
  96.   },
  97.   { 2, // 4
  98.     "name",
  99.     "date",
  100.     "size"
  101.   },
  102.   { 2, // 5
  103.     "first",
  104.     "mix",
  105.     "last"
  106.   },
  107.   { 1, // 6
  108.     "ascending",
  109.     "descending"
  110.   },
  111.   { 5, // 7
  112.     "default",
  113.     "centre in window",
  114.     "centre on screen",
  115.     "top left of window",
  116.     "top left of screen",
  117.     "mouse pointer"
  118.   },
  119.   { 2, // 8
  120.     "Workbench",
  121.     "system",
  122.     "screen"
  123.   },
  124.   { 3, // 9
  125.     "JAM1",
  126.     "JAM2",
  127.     "complement",
  128.     "inverse video"
  129.   },
  130.   { 1, // 10
  131.     "PostScript",  // DM_POSTSCRIPT
  132.     "pass through" // DM_PASSTHROUGH
  133.   },
  134.   { 3, // 11
  135.     "US Letter",   // PF_USLETTER
  136.     "US Legal",    // PF_USLEGAL
  137.     "A4",          // PF_A4
  138.     "custom"       // PF_CUSTOM
  139.   },
  140.   { 8, // 12
  141.     "Courier",
  142.     "Times",
  143.     "Helvetica",
  144.     "Helvetica Narrow",
  145.     "Avant Garde",
  146.     "Bookman",
  147.     "New Century",
  148.     "Palantino",
  149.     "Zapf Chancery"
  150.   },
  151.   { 2, // 13
  152.     "normal",
  153.     "compressed",
  154.     "expanded"
  155.   },
  156.   { 1, // 14
  157.     "portrait",
  158.     "landscape"
  159.   },
  160.   { 4, // 15
  161.     "4 characters",
  162.     "8 characters",
  163.     "quarter-inch",
  164.     "half-inch",
  165.     "inch"
  166.   },
  167.   { 1, // 16
  168.     "positive",
  169.     "negative"
  170.   },
  171.   { 2, // 17
  172.     "black and white", // SHAD_BW
  173.     "greyscale",       // SHAD_GREYSCALE
  174.     "colour"           // SHAD_COLOR
  175.   },
  176.   { 4, // 18
  177.     "default",    // DITH_DEFAULT
  178.     "dotty",      // DITH_DOTTY
  179.     "vertical",   // DITH_VERT
  180.     "horizontal", // DITH_HORIZ
  181.     "diagonal"    // DITH_DIAG
  182.   },
  183.   { 1, // 19
  184.     "horizontal", // ASP_HORIZ
  185.     "vertical"    // ASP_VERT
  186.   },
  187.   { 6, // 20
  188.     "aspect as is", // ST_ASPECT_ASIS
  189.     "aspect wide",  // ST_ASPECT_WIDE
  190.     "aspect tall",  // ST_ASPECT_TALL
  191.     "aspect both",  // ST_ASPECT_BOTH
  192.     "fits wide",    // ST_FITS_WIDE
  193.     "fits tall",    // ST_FITS_TALL
  194.     "fits both"     // ST_FITS_BOTH
  195.   },
  196.   { 3, // 21
  197.     "none",       // CENT_NONE
  198.     "horizontal", // CENT_HORIZ
  199.     "vertical",   // CENT_VERT
  200.     "both"        // CENT_BOTH
  201.   },
  202.   { 3, // 22
  203.     "black and white", // PS_BW
  204.     "greyscale 1",     // PS_GREYSCALE
  205.     "colour",          // PS_COLOR
  206.     "greyscale 2"      // PS_GREY_SCALE2
  207.   },
  208.   { 4, // 23
  209.     "ignore",         // PD_IGNORE
  210.     "bounded",        // PD_BOUNDED
  211.     "absolute",       // PD_ABSOLUTE
  212.     "printer pixels", // PD_PIXEL
  213.     "multiply"        // PD_MULTIPLY
  214.   },
  215.   { 2, // 24
  216.     "ordered",        // PD_ORDERED
  217.     "halftone",       // PD_HALFTONE
  218.     "Floyd-Steinberg" // PD_FLOYD
  219.   },
  220.   { 1, // 25
  221.     "parallel",       // PP_PARALLEL
  222.     "serial"          // PP_SERIAL
  223.   },
  224.   { 1, // 26
  225.     "fanfold",        // PT_FANFOLD
  226.     "single sheet"    // PT_SINGLE
  227.   },
  228.   { 13, // 27
  229.     "US Letter",      // PS_US_LETTER
  230.     "US Legal",       // PS_US_LEGAL
  231.     "narrow tractor", // PS_N_TRACTOR
  232.     "wide tractor",   // PS_W_TRACTOR
  233.     "custom",         // PS_CUSTOM
  234.     "A0: 841x1189mm", // PS_EURO_A0
  235.     "A1: 594x841mm",  // PS_EURO_A1
  236.     "A2: 420x594mm",  // PS_EURO_A2
  237.     "A3: 297x420mm",  // PS_EURO_A3
  238.     "A4: 210x297mm",  // PS_EURO_A4
  239.     "A5: 148x210mm",  // PS_EURO_A5
  240.     "A6: 105x148mm",  // PS_EURO_A6
  241.     "A7: 74x105mm",   // PS_EURO_A7
  242.     "A8: 52x74mm",    // PS_EURO_A8
  243.   },
  244.   { 2, // 28
  245.     "Pica",  // PP_PICA
  246.     "Elite", // PP_ELITE
  247.     "Fine"   // PP_FINE
  248.   },
  249.   { 1, // 29
  250.     "6 lines per inch", // PS_SIX_LPI
  251.     "8 lines per inch", // PS_EIGHT_LPI
  252.   },
  253.   { 1, // 30
  254.     "draft", // PQ_DRAFT
  255.     "letter" // PQ_LETTER
  256.   },
  257.   { 1, // 31
  258.     "beep",  // SPTYPE_BEEP
  259.     "sample" // SPTYPE_SAMPLE
  260.   },
  261.   { 2, // 32
  262.     "Workbench", // WBP_ROOT
  263.     "window",    // WBP_DRAWER
  264.     "screen"     // WBP_SCREEN
  265.   },
  266.   { 1, // 33
  267.     "normal",
  268.     "busy"
  269.   },
  270.   { 6, // 34
  271.     "default",        // POINTERXRESN_DEFAULT
  272.     "140ns",          // POINTERXRESN_140NS
  273.     "70ns",           // POINTERXRESN_70NS
  274.     "35ns",           // POINTERXRESN_35NS
  275.     "screen",         // POINTERXRESN_SCREENRES
  276.     "low resolution", // POINTERXRESN_LORES
  277.     "high resolution" // POINTERXRESN_HIRES
  278.   },
  279.   { 4, // 35
  280.     "default",           // POINTERYRESN_DEFAULT
  281.     "high non-aspect",   // POINTERYRESN_HIGH
  282.     "high aspect",       // POINTERYRESN_HIGHASPECT
  283.     "screen non-aspect", // POINTERYRESN_SCREENRES
  284.     "screen aspect"      // POINTERYRESN_SCREENRESASPECT
  285.   },
  286.   { 3, // 36
  287.     "none",
  288.     "low",
  289.     "high",
  290.     "all"
  291.   },
  292.   { 4, // 37
  293.     "GadTools 2:1",
  294.     "ReAction 1:1",
  295.     "ReAction 2:1",
  296.     "XEN 2:1",
  297.     "XEN 1:1"
  298.   },
  299.   { 2, // 38
  300.     "GadTools", // GLT_GT
  301.     "flat",     // GLT_FLAT
  302.     "3D"        // GLT_3D
  303.   },
  304.   { 2, // 39
  305.     "centre",
  306.     "left",
  307.     "right"
  308.   },
  309.   { 1, // 40
  310.     "Find by name",
  311.     "Find on MIDI"
  312.   },
  313.   { 4, // 41
  314.     "1, 2, 3...",
  315.     "I, II, III...",
  316.     "i, ii, iii...",
  317.     "A, B, C...",
  318.     "a, b, c..."
  319.   },
  320.   { 3, // 42
  321.     "none",
  322.     "left",
  323.     "right",
  324.     "both"
  325.   },
  326.   { 3, // 43
  327.     "left",
  328.     "centre",
  329.     "right",
  330.     "full"
  331.   },
  332.   { 3, // 44
  333.     "left",
  334.     "centre",
  335.     "right",
  336.     "decimal"
  337.   },
  338.   { 3, // 45
  339.     "opaque",
  340.     "mask plane",
  341.     "transparent colour",
  342.     "lasso"
  343.   },
  344.   { 1, // 46
  345.     "none",
  346.     "byte run encoding"
  347.   },
  348.   { 2, // 47
  349.     "no looping",
  350.     "forwards looping",
  351.     "forwards/backwards looping"
  352.   },
  353.   { 1, // 48
  354.     "none",
  355.     "Fibonacci-delta encoding"
  356.   },
  357.   { 6, // 49
  358.     "set directly",
  359.     "XOR ILBM",
  360.     "long delta",
  361.     "short delta",
  362.     "short/long delta",
  363.     "byte vertical delta",
  364.     "stereo op 5"
  365.   },
  366.   { 3, // 50
  367.     "metric",   // MS_ISO
  368.     "American", // MS_AMERICAN
  369.     "Imperial", // MS_IMPERIAL
  370.     "British"   // MS_BRITISH
  371.   },
  372.   { 1, // 51
  373.     "No", // SS_NOSPACE
  374.     "Yes" // SS_SPACE
  375.   },
  376.   { 4, // 52
  377.     "parentheses around amount and symbol", // SP_PARENS
  378.     "sign is before amount and symbol",     // SP_PREC_ALL
  379.     "sign is after amount and symbol",      // SP_SUCC_ALL
  380.     "sign is before symbol",                // SP_PREC_CURR
  381.     "sign is after symbol"                  // SP_SUCC_CURR
  382.   },
  383.   { 1, // 53
  384.     "symbol is before amount", // CSP_PRECEDES
  385.     "symbol is after amount"   // CSP_SUCCEEDS
  386.   },
  387.   { 6, // 54
  388.     "Sunday",
  389.     "Monday",
  390.     "Tuesday",
  391.     "Wednesday",
  392.     "Thursday",
  393.     "Friday",
  394.     "Saturday"
  395. } };
  396.  
  397. /* Text error messages for possible IFFERR_#? returns from various IFF
  398.  * routines. To get the index into this array, take your IFFERR code,
  399.  * negate it, and subtract one.
  400.  * idx = -error - 1;
  401.  */
  402. STRPTR errormsgs[] =
  403. {   "End of file (not an error).",
  404.     "End of context (not an error).",
  405.     "No lexical scope.",
  406.     "Insufficient memory.",
  407.     "Stream read error.",
  408.     "Stream write error.",
  409.     "Stream seek error.",
  410.     "File is corrupt.",
  411.     "IFF syntax error.",
  412.     "Not an IFF file.",
  413.     "Required call-back hook missing.",
  414.     "Return to client. You should never see this."
  415. };
  416.  
  417. // from rp.c
  418. IMPORT SBYTE              page;
  419. IMPORT struct Window*     MainWindowPtr;
  420. IMPORT struct TextAttr    Topaz8;
  421. IMPORT TEXT               aslresult[VLONGFIELD + 1],
  422.                           weekdaystring[LEN_DATSTRING],
  423.                           datestring[LEN_DATSTRING],
  424.                           timestring[LEN_DATSTRING],
  425.                           IOBuffer[LONGESTFIELD + 1];
  426. IMPORT Object*            WinObject[FUNCTIONS + 1]; // note that WindowObject is a reserved macro
  427. IMPORT struct Menu*       MenuPtr;
  428. IMPORT struct Screen*     ScreenPtr;
  429.  
  430. MODULE ABOOL             known, first;
  431. MODULE struct IFFHandle* IFFHandle             = NULL;
  432. MODULE struct List       List1,
  433.                          List2;
  434. MODULE TEXT  queryform[5] = "",
  435.              tempstring1[VLONGFIELD + 1],
  436.              tempstring2[13], // only for use with numbers
  437.              tempstring3[VLONGFIELD + 1];
  438. MODULE ULONG items        = 0; // value of this is actual number of items allocated
  439. MODULE UWORD selectedform  = 0,
  440.              selectedchunk = 0;
  441. MODULE struct Gadget*    iff_gadgets[GIDS_6 + 1];
  442.     
  443. AGLOBAL struct IFFStruct iff;
  444.  
  445. MODULE struct
  446. {   UBYTE  flags;
  447.     TEXT   name[5];
  448.     STRPTR desc;
  449.     STRPTR contributor;
  450. } form[FORMS + 1] =
  451. {   STANDARD | RKM | CD,      "8SVX", "EA IFF 85 8-bit sound sample form",                    "EA/CBM",
  452.     RKM | CD,                 "AIFF", "Audio 1-32 bit samples",                               "Apple",
  453.     RKM | CD,                 "ACBM", "Amiga Contiguous Bitmap",                              "CBM",
  454.     UNREGISTERED,             "AHAM", "?",                                                    "?",
  455.     RKM | CD,                 "ANBM", "ANimated BitMap form",                                 "EA",
  456.     RKM | CD,                 "ANIM", "Cel ANIMation form",                                   "Sparta/Aegis",
  457.     PROPOSAL,                 "ARC ", "ARChive format",                                       "?",
  458.     UNREGISTERED,             "ARES", "?",                                                    "?",
  459.     RESERVED,                 "ATXT", "Temporarily reserved",                                 "?",
  460.     PRIVATE,                  "AVCF", "AmigaVision Flow",                                     "CBM",
  461.     NULL,                     "BANK", "Soundquest Editor/Librarian MIDI Sysex dump",          "?",
  462.     NULL,                     "BBSD", "BBS Database",                                         "Phalanx Software",
  463.     PRIVATE,                  "C100", "?",                                                    "Cloanto",
  464.     STANDARD,                 "CAT ", "EA IFF 85 group identifier",                           "EA/CBM",
  465.     PROPOSAL,                 "CELP", "Compressed ZyXEL voice data",                          "?",
  466.     RESERVED,                 "CHBM", "Chunky bitmap",                                        "Eric Lavitsky",
  467.     NULL,                     "CLIP", "CAT CLIP to hold various formats in clipboard",        "CBM",
  468.     PROPOSAL | CD,            "CMUS", "Common MUsical Score",                                 "Talin (David Joiner)",
  469.     NULL,                     "CPFM", "Cloanto Personal FontMaker",                           "Cloanto",
  470.     UNREGISTERED,             "CTLG", "Language CaTaLoG",                                     "CBM",
  471.     NULL,                     "DCCL", "DCTV paint clip",                                      "?",
  472.     NULL,                     "DCPA", "DCTV paint palette",                                   "?",
  473.     NULL,                     "DCTV", "DCTV raw picture file",                                "?",
  474.     PRIVATE,                  "DECK", "Inovatronics CanDo",                                   "Innovatronics",
  475.     CD,                       "DEEP", "Chunky pixel image files (used in TV Paint)",          "Amiga Centre Scotland",
  476.     RKM | CD,                 "DR2D", "2D object standard format",                            "Ross Cunniff & John Orr",
  477.     RESERVED,                 "DRAW", "?",                                                    "Jim Bayless",
  478.     CD,                       "DTYP", "DataTYPes identification",                             "Amiga, Inc.",
  479.     PROPOSAL | CD,            "EXEC", "Executable (loadseg-able) code",                       "Chris Ludwig",
  480.     RKM | CD,                 "FANT", "Fantavision movie format",                             "Broderbund",
  481.     OBSOLETE | PRIVATE,       "FAX3", "Facsimile image",                                      "GPSoftware",
  482.     CD,                       "FAXX", "Facsimile image",                                      "Atlantis Design Group",
  483.     RESERVED,                 "FIGR", "Deluxe Video",                                         "EA",
  484.     NULL,                     "FILM", "LIST FILM - stores ILBMs with interleaved 8SVX audio", "?",
  485.     RESERVED,                 "FNTR", "Raster font",                                          "EA",
  486.     RESERVED,                 "FNTV", "Vector font",                                          "EA",
  487.     STANDARD,                 "FORM", "Group identifier",                                     "EA/CBM",
  488.     STANDARD | RKM,           "FTXT", "Formatted TeXT",                                       "EA/CBM",
  489.     PROPOSAL | PRIVATE,       "GRYP", "Byteplane storage",                                    "?",
  490.     RESERVED,                 "GSCR", "General music SCoRe",                                  "EA",
  491.     PROPOSAL | PRIVATE,       "GUI ", "User interface storage",                               "?",
  492.     RKM | CD,                 "HEAD", "Flow idea processor",                                  "New Horizons Software",
  493.     STANDARD | RKM | CD,      "ILBM", "EA IFF 85 raster bitmap form",                         "EA/CBM",
  494.     RESERVED,                 "IOBJ", "?",                                                    "Seven Seas Software",
  495.     RESERVED,                 "IODK", "?",                                                    "Merging Technologies",
  496.     RESERVED,                 "ITRF", "?",                                                    "?",
  497.     RESERVED,                 "JMOV", "?",                                                    "Merging Technologies",
  498.     STANDARD,                 "LIST", "EA IFF 85 group identifier",                           "EA/CBM",
  499.     RESERVED,                 "MFAX", "Facsimile?",                                           "TKR GmbH & Co.",
  500.     NULL,                     "MIDI", "MIDI?",                                                "Circum Design",
  501.     PRIVATE,                  "MOVI", "LIST MOVIe?",                                          "?",
  502.     PRIVATE,                  "MSCX", "Music-X format",                                       "?",
  503.     RESERVED,                 "MSMP", "Temporarily reserved",                                 "?",
  504.     RKM | CD,                 "MTRX", "Numerical data storage (MathVision)",                  "Seven Seas Software",
  505.     NULL,                     "NSEQ", "Numerical sequence",                                   "Stockhausen GmbH",
  506.     PROPOSAL | CD,            "OB3D", "Standard 3D object",                                   "?",
  507.     RKM | CD,                 "PGTB", "ProGram TraceBack",                                    "SAS Institute",
  508.     RESERVED,                 "PICS", "Macintosh picture",                                    "EA",
  509.     RESERVED | OBSOLETE,      "PLBM", "?",                                                    "EA",
  510.     RESERVED | PROPOSAL | CD, "PMBC", "24-bit accurate images",                               "Black Belt Systems",
  511.     RESERVED | PRIVATE,       "PREF", "User preferences data",                                "CBM",
  512.     STANDARD,                 "PROP", "Group identifier",                                     "EA/CBM",
  513.     RKM | CD,                 "PRSP", "DPaint IV perspective move form",                      "EA",
  514.     NULL,                     "PTCH", "Patch file",                                           "SAS Institute",
  515.     RESERVED,                 "PTXT", "Temporarily reserved",                                 "?",
  516.     PRIVATE,                  "RGB4", "4-bit RGB",                                            "?",
  517.     RKM | CD,                 "RGB8", "RGB image (Turbo Silver)",                             "Impulse",
  518.     RKM | CD,                 "RGBN", "RGB image (Turbo Silver)",                             "Impulse",
  519.     RESERVED,                 "RGBX", "Temporarily reserved",                                 "?",
  520.     PRIVATE,                  "ROXN", "Animation",                                            "?",
  521.     UNREGISTERED,             "RSND", "Sampled SouND",                                        "Achim Stegemann",
  522.     RKM | CD,                 "SAMP", "SAMPled sound",                                        "Jim Fiore & Jeff Glatt",
  523.     PRIVATE,                  "SC3D", "SCene format (Sculpt-3D)",                             "?",
  524.     PRIVATE,                  "SHAK", "SHAKespeare format",                                   "?",
  525.     RESERVED | PRIVATE,       "SHO1", "?",                                                    "Gary Bonham",
  526.     RESERVED | PRIVATE,       "SHOW", "?",                                                    "Gary Bonham",
  527.     STANDARD | RKM,           "SMUS", "Simple MUsic Score",                                   "EA/CBM",
  528.     CD,                       "SPLT", "File SPLiTting system",                                "ASDG",
  529.     RESERVED,                 "SSRE", "?",                                                    "Merging Technologies",
  530.     UNREGISTERED,             "SWRT", "?",                                                    "?",
  531.     NULL,                     "SYTH", "SoundQuest Master Librarian MIDI System driver",       "?",
  532.     RESERVED,                 "TCDE", "?",                                                    "Merging Technologies",
  533.     RKM | CD,                 "TDDD", "3D rendering data (Turbo Silver)",                     "Impulse",
  534.     UNREGISTERED,             "TERM", "?",                                                    "?",
  535.     CD,                       "TMUI", "ToolMaker User Interface",                             "Michael Erwin",
  536.     CD,                       "TREE", "Arbitrary data structures as trees (or nested lists)", "Stefan Reisner",
  537.     CD | PROPOSAL,            "TRKR", "TRacKeR style music module",                           "Full Tilt Entertainment",
  538.     RESERVED,                 "USCR", "Uhuru SCoRe",                                          "EA",
  539.     RESERVED,                 "UVOX", "Uhuru Macintosh VOiXe",                                "EA",
  540.     PRIVATE,                  "VDEO", "Deluxe ViDEO",                                         "EA",
  541.     RKM | CD,                 "WORD", "ProWrite document",                                    "New Horizons Software",
  542.     UNREGISTERED,             "WOWO", "WordWorth document",                                   "Digita",
  543.     CD,                       "YUVN", "For storage of Y:U:V image data",                      "MacroSystem"
  544. };
  545.  
  546. AGLOBAL void iff1(void)
  547. {   struct Hook Hook6Struct;
  548.     STRPTR      stringptr;
  549.  
  550.     InitHook(&Hook6Struct, Hook6Func, NULL);
  551.  
  552.     /* Create the window object. */
  553.     lockscreen();
  554.  
  555. if (!(WinObject[6] =
  556. NewObject
  557. (   WINDOW_GetClass(),                    NULL,
  558.     WA_PubScreen,                         ScreenPtr,
  559.     WA_ScreenTitle,                       "Report+",
  560.     WA_Title,                             "Report+: IFF FORM Viewer",
  561.     WA_Activate,                          TRUE,
  562.     WA_DepthGadget,                       TRUE,
  563.     WA_DragBar,                           TRUE,
  564.     WA_CloseGadget,                       TRUE,
  565.     WA_SizeGadget,                        TRUE,
  566.     WA_IDCMP,                             IDCMP_RAWKEY,
  567.     WINDOW_IDCMPHook,                     &Hook6Struct,
  568.     WINDOW_IDCMPHookBits,                 IDCMP_RAWKEY,
  569.     WINDOW_MenuStrip,                     MenuPtr,
  570.     WINDOW_Position,                      WPOS_CENTERSCREEN,
  571.     WINDOW_ParentGroup,                   iff_gadgets[GID_6_LY1] =
  572.     NewObject
  573.     (   LAYOUT_GetClass(),                NULL,
  574.         LAYOUT_Orientation,               LAYOUT_ORIENT_VERT,
  575.         LAYOUT_SpaceOuter,                TRUE,
  576.         LAYOUT_DeferLayout,               TRUE,
  577.         LAYOUT_AddChild,
  578.         NewObject
  579.         (   LAYOUT_GetClass(),            NULL,
  580.             LAYOUT_Orientation,           LAYOUT_ORIENT_HORIZ,
  581.             LAYOUT_DeferLayout,           TRUE,
  582.             LAYOUT_BevelStyle,            BVS_NONE,
  583.             LAYOUT_AddChild,
  584.             NewObject
  585.             (   LAYOUT_GetClass(),        NULL,
  586.                 LAYOUT_Orientation,       LAYOUT_ORIENT_VERT,
  587.                 LAYOUT_VertAlignment,     LALIGN_CENTER,
  588.                 LAYOUT_SpaceOuter,        TRUE,
  589.                 LAYOUT_BevelStyle,        BVS_FIELD,
  590.                 LAYOUT_AddChild,
  591.                 NewObject
  592.                 (   LAYOUT_GetClass(),        NULL,
  593.                     LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  594.                     LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  595.                     LAYOUT_VertAlignment,     LALIGN_CENTER,
  596.                     LAYOUT_BevelStyle,        BVS_NONE,
  597.                     LAYOUT_AddImage,
  598.                     NewObject
  599.                     (   LABEL_GetClass(),     NULL,
  600.                         LABEL_Text,           "_FORM ID:",
  601.                         LABEL_Justification,  LJ_RIGHT,
  602.                     TAG_END),
  603.                 TAG_END),
  604.                 LAYOUT_AddChild,
  605.                 NewObject
  606.                 (   LAYOUT_GetClass(),        NULL,
  607.                     LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  608.                     LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  609.                     LAYOUT_VertAlignment,     LALIGN_CENTER,
  610.                     LAYOUT_BevelStyle,        BVS_NONE,
  611.                     LAYOUT_AddImage,
  612.                     NewObject
  613.                     (   LABEL_GetClass(),     NULL,
  614.                         LABEL_Text,           "Description:",
  615.                         LABEL_Justification,  LJ_RIGHT,
  616.                     TAG_END),
  617.                 TAG_END),
  618.                 LAYOUT_AddChild,
  619.                 NewObject
  620.                 (   LAYOUT_GetClass(),        NULL,
  621.                     LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  622.                     LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  623.                     LAYOUT_VertAlignment,     LALIGN_CENTER,
  624.                     LAYOUT_BevelStyle,        BVS_NONE,
  625.                     LAYOUT_AddImage,
  626.                     NewObject
  627.                     (   LABEL_GetClass(),     NULL,
  628.                         LABEL_Text,           "Contributor:",
  629.                         LABEL_Justification,  LJ_RIGHT,
  630.                     TAG_END),
  631.                 TAG_END),
  632.                 LAYOUT_AddChild,
  633.                 NewObject
  634.                 (   LAYOUT_GetClass(),        NULL,
  635.                     LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  636.                     LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  637.                     LAYOUT_VertAlignment,     LALIGN_CENTER,
  638.                     LAYOUT_BevelStyle,        BVS_NONE,
  639.                     LAYOUT_AddImage,
  640.                     NewObject
  641.                     (   LABEL_GetClass(),     NULL,
  642.                         LABEL_Text,           "Chunk info:",
  643.                         LABEL_Justification,  LJ_RIGHT,
  644.                     TAG_END),
  645.                 TAG_END),
  646.                 LAYOUT_AddChild,
  647.                 NewObject
  648.                 (   LAYOUT_GetClass(),        NULL,
  649.                     LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  650.                     LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  651.                     LAYOUT_VertAlignment,     LALIGN_CENTER,
  652.                     LAYOUT_BevelStyle,        BVS_NONE,
  653.                     LAYOUT_AddImage,
  654.                     NewObject
  655.                     (   LABEL_GetClass(),     NULL,
  656.                         LABEL_Text,           "_Pathname:",
  657.                         LABEL_Justification,  LJ_RIGHT,
  658.                     TAG_END),
  659.                 TAG_END),
  660.                 LAYOUT_AddChild,
  661.                 NewObject
  662.                 (   LAYOUT_GetClass(),        NULL,
  663.                     LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  664.                     LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  665.                     LAYOUT_VertAlignment,     LALIGN_CENTER,
  666.                     LAYOUT_BevelStyle,        BVS_NONE,
  667.                     LAYOUT_AddImage,
  668.                     NewObject
  669.                     (   LABEL_GetClass(),     NULL,
  670.                         LABEL_Text,           "Status:",
  671.                         LABEL_Justification,  LJ_RIGHT,
  672.                     TAG_END),
  673.                 TAG_END),
  674.             TAG_END),
  675.             CHILD_WeightedWidth,          0,
  676.             LAYOUT_AddChild,
  677.             NewObject
  678.             (   LAYOUT_GetClass(),        NULL,
  679.                 LAYOUT_Orientation,       LAYOUT_ORIENT_VERT,
  680.                 LAYOUT_VertAlignment,     LALIGN_CENTER,
  681.                 LAYOUT_HorizAlignment,    LALIGN_CENTER,
  682.                 LAYOUT_BevelStyle,        BVS_NONE,
  683.                 LAYOUT_AddChild,
  684.                 NewObject
  685.                 (   LAYOUT_GetClass(),    NULL,
  686.                     LAYOUT_Orientation,   LAYOUT_ORIENT_HORIZ,
  687.                     LAYOUT_VertAlignment, LALIGN_CENTER,
  688.                     LAYOUT_HorizAlignment,LALIGN_LEFT,
  689.                     LAYOUT_BevelStyle,    BVS_NONE,
  690.                     LAYOUT_AddChild,          iff_gadgets[GID_6_ST1] =
  691.                     NewObject
  692.                     (   STRING_GetClass(),    NULL,
  693.                         GA_ID,                GID_6_ST1,
  694.                         GA_TabCycle,          TRUE,
  695.                         GA_RelVerify,         TRUE,
  696.                         STRINGA_TextVal,      queryform,
  697.                         STRINGA_ReplaceMode,  TRUE,
  698.                         STRINGA_MinVisible,   4,
  699.                         STRINGA_MaxChars,     4 + 1,
  700.                     TAG_END),
  701.                     CHILD_WeightedWidth,      50,
  702.                     LAYOUT_AddChild,          iff_gadgets[GID_6_CB1] =
  703.                     NewObject
  704.                     (   CHECKBOX_GetClass(),  NULL,
  705.                         GA_ID,                GID_6_CB1,
  706.                         GA_RelVerify,         TRUE,
  707.                         GA_Text,              "_Raw view only?",
  708.                         GA_Selected,          (BOOL) iff.raw,
  709.                     TAG_END),
  710.                     CHILD_WeightedWidth,      50,
  711.                 TAG_END),    
  712.                 LAYOUT_AddChild,          iff_gadgets[GID_6_ST2] =
  713.                 NewObject
  714.                 (   STRING_GetClass(),    NULL,
  715.                     GA_ID,                GID_6_ST2,
  716.                     GA_ReadOnly,          TRUE,
  717.                     STRINGA_TextVal,      "-",
  718.                     STRINGA_MinVisible,   20,
  719.                 TAG_END),
  720.                 LAYOUT_AddChild,          iff_gadgets[GID_6_ST3] =
  721.                 NewObject
  722.                 (   STRING_GetClass(),    NULL,
  723.                     GA_ID,                GID_6_ST3,
  724.                     GA_ReadOnly,          TRUE,
  725.                     STRINGA_TextVal,      "-",
  726.                     STRINGA_MinVisible,   20,
  727.                 TAG_END),
  728.                 LAYOUT_AddChild,          iff_gadgets[GID_6_ST4] =
  729.                 NewObject
  730.                 (   STRING_GetClass(),    NULL,
  731.                     GA_ID,                GID_6_ST4,
  732.                     GA_ReadOnly,          TRUE,
  733.                     STRINGA_TextVal,      "-",
  734.                     STRINGA_MinVisible,   20,
  735.                 TAG_END),
  736.                 LAYOUT_AddChild,
  737.                 NewObject
  738.                 (   LAYOUT_GetClass(),    NULL,
  739.                     LAYOUT_Orientation,   LAYOUT_ORIENT_HORIZ,
  740.                     LAYOUT_VertAlignment, LALIGN_CENTER,
  741.                     LAYOUT_HorizAlignment,LALIGN_LEFT,
  742.                     LAYOUT_BevelStyle,    BVS_NONE,
  743.                     LAYOUT_AddChild,          iff_gadgets[GID_6_ST6] =
  744.                     NewObject
  745.                     (   STRING_GetClass(),    NULL,
  746.                         GA_ID,                GID_6_ST6,
  747.                         GA_RelVerify,         TRUE,
  748.                         GA_TabCycle,          TRUE,
  749.                         STRINGA_TextVal,      iff.pathname,
  750.                         STRINGA_MinVisible,   20,
  751.                         STRINGA_MaxChars,     PATHNAMEFIELD,
  752.                     TAG_END),
  753.                     LAYOUT_AddChild,      iff_gadgets[GID_6_BU1] =
  754.                     NewObject
  755.                     (   NULL,             "button.gadget",
  756.                         GA_ID,            GID_6_BU1,
  757.                         GA_RelVerify,     TRUE,
  758.                         BUTTON_AutoButton,BAG_POPFILE,
  759.                     TAG_END),
  760.                     CHILD_WeightedWidth,  0,
  761.                 TAG_END),
  762.                 CHILD_WeightedHeight,     0,
  763.                 LAYOUT_AddChild,          iff_gadgets[GID_6_ST5] =
  764.                 NewObject
  765.                 (   STRING_GetClass(),    NULL,
  766.                     GA_ID,                GID_6_ST5,
  767.                     GA_ReadOnly,          TRUE,
  768.                     STRINGA_TextVal,      "Ready.",
  769.                     STRINGA_MinVisible,   20,
  770.                 TAG_END),
  771.             TAG_END),
  772.             CHILD_WeightedWidth,          100,
  773.             LAYOUT_AddChild,
  774.             NewObject
  775.             (   LAYOUT_GetClass(),        NULL,
  776.                 LAYOUT_Orientation,       LAYOUT_ORIENT_VERT,
  777.                 LAYOUT_SpaceOuter,        TRUE,
  778.                 LAYOUT_VertAlignment,     LALIGN_CENTER,
  779.                 LAYOUT_HorizAlignment,    LALIGN_LEFT,
  780.                 LAYOUT_BevelStyle,        BVS_FIELD,
  781.                 LAYOUT_AddImage,
  782.                 NewObject
  783.                 (   LABEL_GetClass(),     NULL,
  784.                     LABEL_Text,           "FORM Status:",
  785.                     LABEL_Justification,  LJ_RIGHT,
  786.                 TAG_END),
  787.                 LAYOUT_AddChild,          iff_gadgets[GID_6_CB2] =
  788.                 NewObject
  789.                 (   CHECKBOX_GetClass(),  NULL,
  790.                     GA_ID,                GID_6_CB2,
  791.                     GA_Disabled,          TRUE,
  792.                     GA_Text,              "Obsolete?",
  793.                     GA_Selected,          (BOOL) iff.obsolete,
  794.                 TAG_END),
  795.                 LAYOUT_AddChild,          iff_gadgets[GID_6_CB3] =
  796.                 NewObject
  797.                 (   CHECKBOX_GetClass(),  NULL,
  798.                     GA_ID,                GID_6_CB3,
  799.                     GA_Disabled,          TRUE,
  800.                     GA_Text,              "Private?",
  801.                     GA_Selected,          (BOOL) iff.private,
  802.                 TAG_END),
  803.                 LAYOUT_AddChild,          iff_gadgets[GID_6_CB4] =
  804.                 NewObject
  805.                 (   CHECKBOX_GetClass(),  NULL,
  806.                     GA_ID,                GID_6_CB4,
  807.                     GA_Disabled,          TRUE,
  808.                     GA_Text,              "Proposal?",
  809.                     GA_Selected,          (BOOL) iff.proposal,
  810.                 TAG_END),
  811.                 LAYOUT_AddChild,          iff_gadgets[GID_6_CB5] =
  812.                 NewObject
  813.                 (   CHECKBOX_GetClass(),  NULL,
  814.                     GA_ID,                GID_6_CB5,
  815.                     GA_Disabled,          TRUE,
  816.                     GA_Text,              "Reserved?",
  817.                     GA_Selected,          (BOOL) iff.reserved,
  818.                 TAG_END),
  819.                 LAYOUT_AddChild,          iff_gadgets[GID_6_CB6] =
  820.                 NewObject
  821.                 (   CHECKBOX_GetClass(),  NULL,
  822.                     GA_ID,                GID_6_CB6,
  823.                     GA_Disabled,          TRUE,
  824.                     GA_Text,              "Standard?",
  825.                     GA_Selected,          (BOOL) iff.standard,
  826.                 TAG_END),
  827.                 LAYOUT_AddChild,          iff_gadgets[GID_6_CB7] =
  828.                 NewObject
  829.                 (   CHECKBOX_GetClass(),  NULL,
  830.                     GA_ID,                GID_6_CB7,
  831.                     GA_Disabled,          TRUE,
  832.                     GA_Text,              "Unregistered?",
  833.                     GA_Selected,          (BOOL) iff.unregistered,
  834.                 TAG_END),
  835.             TAG_END),
  836.             CHILD_WeightedWidth,          0,
  837.         TAG_END),
  838.         CHILD_WeightedHeight,             0,
  839.         LAYOUT_AddChild,
  840.         NewObject
  841.         (   LAYOUT_GetClass(),            NULL,
  842.             LAYOUT_Orientation,           LAYOUT_ORIENT_HORIZ,
  843.             LAYOUT_HorizAlignment,        LALIGN_CENTER,
  844.             LAYOUT_BevelStyle,            BVS_NONE,
  845.             LAYOUT_AddChild,
  846.             NewObject
  847.             (   LAYOUT_GetClass(),        NULL,
  848.                 LAYOUT_Orientation,       LAYOUT_ORIENT_VERT,
  849.                 LAYOUT_HorizAlignment,    LALIGN_CENTER,
  850.                 LAYOUT_BevelStyle,        BVS_NONE,
  851.                 LAYOUT_AddImage,
  852.                 NewObject
  853.                 (   LABEL_GetClass(),     NULL,
  854.                     LABEL_Text,           "Chunks:",
  855.                     LABEL_Justification,  LJ_CENTER,
  856.                 TAG_END),
  857.                 CHILD_WeightedHeight,     0,
  858.                 LAYOUT_AddChild,          iff_gadgets[GID_6_LB1] =
  859.                 NewObject
  860.                 (   LISTBROWSER_GetClass(),NULL,
  861.                     GA_ID,                 GID_6_LB1,
  862.                     GA_RelVerify,          TRUE,
  863.                     GA_TextAttr,           &Topaz8,
  864.                     LISTBROWSER_Labels,    (ULONG) &List1,
  865.                 TAG_END),
  866.                 CHILD_MinWidth,            140,
  867.             TAG_END),
  868.             CHILD_WeightedWidth,           100,
  869.             LAYOUT_AddChild,
  870.             NewObject
  871.             (   LAYOUT_GetClass(),        NULL,
  872.                 LAYOUT_Orientation,       LAYOUT_ORIENT_VERT,
  873.                 LAYOUT_HorizAlignment,    LALIGN_CENTER,
  874.                 LAYOUT_BevelStyle,        BVS_NONE,
  875.                 LAYOUT_AddImage,
  876.                 NewObject
  877.                 (   LABEL_GetClass(),     NULL,
  878.                     LABEL_Text,           "Chunk contents:",
  879.                     LABEL_Justification,  LJ_CENTER,
  880.                 TAG_END),
  881.                 CHILD_WeightedHeight,     0,
  882.                 LAYOUT_AddChild,          iff_gadgets[GID_6_LB2] =
  883.                 NewObject
  884.                 (   LISTBROWSER_GetClass(),NULL,
  885.                     GA_ID,                 GID_6_LB2,
  886.                     GA_RelVerify,          TRUE,
  887.                     GA_TextAttr,           &Topaz8,
  888.                     LISTBROWSER_Labels,    (ULONG) &List2,
  889.                 TAG_END),
  890.                 CHILD_MinWidth,           456,
  891.                 CHILD_MaxWidth,           456,
  892.             TAG_END),
  893.             CHILD_WeightedWidth,          0,
  894.         TAG_END),
  895.         CHILD_WeightedHeight,             100,
  896.         CHILD_MinHeight,                  160,
  897.         LAYOUT_AddChild,
  898.         NewObject
  899.         (   LAYOUT_GetClass(),        NULL,
  900.             LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  901.             LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  902.             LAYOUT_VertAlignment,     LALIGN_CENTER,
  903.             LAYOUT_BevelStyle,        BVS_NONE,
  904.             LAYOUT_AddImage,
  905.             NewObject
  906.             (   LABEL_GetClass(),     NULL,
  907.                 LABEL_Text,           "Documents:",
  908.                 LABEL_Justification,  LJ_RIGHT,
  909.             TAG_END),
  910.             CHILD_WeightedWidth,      0,
  911.             LAYOUT_AddChild,          iff_gadgets[GID_6_CB8] =
  912.             NewObject
  913.             (   CHECKBOX_GetClass(),  NULL,
  914.                 GA_ID,                GID_6_CB8,
  915.                 GA_Disabled,          TRUE,
  916.                 GA_Text,              "RKM?",
  917.                 GA_Selected,          (BOOL) iff.rkm,
  918.             TAG_END),
  919.             CHILD_WeightedWidth,      0,
  920.             LAYOUT_AddChild,          iff_gadgets[GID_6_CB9] =
  921.             NewObject
  922.             (   CHECKBOX_GetClass(),  NULL,
  923.                 GA_ID,                GID_6_CB9,
  924.                 GA_Disabled,          TRUE,
  925.                 GA_Text,              "ADCD 2.1?",
  926.                 GA_Selected,          (BOOL) iff.cd,
  927.             TAG_END),
  928.             CHILD_WeightedWidth,       0,
  929.             LAYOUT_AddImage,           NewObject
  930.             (   LABEL_GetClass(),      NULL,
  931.                 LABEL_Text,            "",
  932.             TAG_END),
  933.             CHILD_WeightedWidth,       100,
  934.         TAG_END),
  935.         CHILD_WeightedHeight,          0,
  936.     TAG_END),
  937. TAG_END)))
  938. {   rq("Can't create ReAction gadgets!");
  939. }
  940. unlockscreen();
  941. openwindow();
  942.  
  943.     if (iff.pathname[0])
  944.     {   readiff();
  945.     } elif (queryform[0])
  946.     {   iffquery();
  947.     }
  948.  
  949.     ActivateLayoutGadget(iff_gadgets[GID_6_LY1], MainWindowPtr, NULL, (Object) iff_gadgets[GID_6_ST6]);
  950.  
  951.     loop();
  952.  
  953.     if (!(GetAttr
  954.     (   STRINGA_TextVal, iff_gadgets[GID_6_ST1], (ULONG *) &stringptr
  955.     )))
  956.     {   rq("Unsupported inquiry!"); // should never happen
  957.     }
  958.     strcpy(queryform, stringptr);
  959.  
  960.     if (!(GetAttr
  961.     (   STRINGA_TextVal, iff_gadgets[GID_6_ST6], (ULONG *) &stringptr
  962.     )))
  963.     {   rq("Unsupported inquiry!"); // should never happen
  964.     }
  965.     strcpy(iff.pathname, stringptr);
  966.  
  967.     closewindow();
  968.     // now that the window is closed we can free lists
  969.     iff_exit();
  970. }
  971.  
  972. AGLOBAL void iff_loop(ULONG gid)
  973. {   STRPTR stringptr;
  974.     ULONG  code;
  975.  
  976.     switch(gid)
  977.     {
  978.     case GID_6_CB1:
  979.         if (!(GetAttr
  980.         (   GA_Selected, iff_gadgets[GID_6_CB1], (ULONG *) &iff.raw
  981.         )))
  982.         {   rq("Unsupported inquiry!"); // should never happen
  983.         }
  984.         if (selectedchunk && known)
  985.         {   tellchunk(selectedchunk);
  986.         }
  987.     break;
  988.     case GID_6_ST1:
  989.         if (!(GetAttr
  990.         (   STRINGA_TextVal, iff_gadgets[GID_6_ST1], (ULONG *) &stringptr
  991.         )))
  992.         {   rq("Unsupported inquiry!"); // should never happen
  993.         }
  994.         strcpy(queryform, stringptr);
  995.  
  996.         iff.pathname[0] = 0;
  997.         SetGadgetAttrs
  998.         (   iff_gadgets[GID_6_ST6],
  999.             MainWindowPtr, NULL,
  1000.             STRINGA_TextVal, iff.pathname,
  1001.             TAG_END
  1002.         );
  1003.         SetGadgetAttrs
  1004.         (   iff_gadgets[GID_6_ST5],
  1005.             MainWindowPtr, NULL,
  1006.             STRINGA_TextVal, "Ready.",
  1007.             TAG_END
  1008.         );
  1009.         iffquery();
  1010.     break;
  1011.     case GID_6_ST6:
  1012.         if (!(GetAttr
  1013.         (   STRINGA_TextVal, iff_gadgets[GID_6_ST6], (ULONG *) &stringptr
  1014.         )))
  1015.         {   rq("Unsupported inquiry!"); // should never happen
  1016.         }
  1017.         strcpy(iff.pathname, stringptr);
  1018.         readiff();
  1019.     break;
  1020.     case GID_6_BU1:
  1021.         if (asl("~(#?.info)"))
  1022.         {   strcpy(iff.pathname, aslresult);
  1023.             SetGadgetAttrs
  1024.             (   iff_gadgets[GID_6_ST6],
  1025.                 MainWindowPtr, NULL,
  1026.                 STRINGA_TextVal, iff.pathname,
  1027.                 TAG_END
  1028.             );
  1029.             readiff();
  1030.         }
  1031.     break;
  1032.     case GID_6_LB1:
  1033.         /* code is the position within the list, starting from 0. */
  1034.  
  1035.         if (!(GetAttr
  1036.         (   LISTBROWSER_Selected, iff_gadgets[GID_6_LB1], (ULONG *) &code
  1037.         )))
  1038.         {   rq("Unsupported inquiry!"); // should never happen
  1039.         }
  1040.         selectedchunk = code + 1;
  1041.         tellchunk(selectedchunk);
  1042.     break;
  1043.     default:
  1044.     break;
  1045. }   }
  1046.  
  1047. MODULE void iffquery(void)
  1048. {   ULONG i;
  1049.  
  1050.     /* Make any corrections to input now, to make it
  1051.     easier to search the database. */
  1052.     for (i = 0; i <= 3; i++)
  1053.         if (queryform[i] >= 97 && queryform[i] <= 122)
  1054.             queryform[i] -= 32;
  1055.         elif (queryform[i] == 0)
  1056.             queryform[i] = ' ';
  1057.     queryform[4] = 0;
  1058.  
  1059.     SetGadgetAttrs
  1060.     (   iff_gadgets[GID_6_ST1],
  1061.         MainWindowPtr, NULL,
  1062.         STRINGA_TextVal, queryform,
  1063.         TAG_END
  1064.     );
  1065.  
  1066.     selectedform = (UWORD) -1;
  1067.     for (i = 0; i <= FORMS; i++)
  1068.     if
  1069.     (   queryform[0] == form[i].name[0]
  1070.      && queryform[1] == form[i].name[1]
  1071.      && queryform[2] == form[i].name[2]
  1072.      && queryform[3] == form[i].name[3]
  1073.     )
  1074.     {   selectedform = i;
  1075.         break;
  1076.     }
  1077.     selectedchunk = 0;
  1078.     if (selectedform == (UWORD) -1)
  1079.     {   iff.cd           =
  1080.         iff.rkm          =
  1081.         iff.private      =
  1082.         iff.proposal     =
  1083.         iff.obsolete     =
  1084.         iff.reserved     =
  1085.         iff.standard     =
  1086.         iff.unregistered = FALSE;
  1087.  
  1088.         SetGadgetAttrs
  1089.         (   iff_gadgets[GID_6_ST2],
  1090.             MainWindowPtr, NULL,
  1091.             STRINGA_TextVal, "-",
  1092.             TAG_END
  1093.         );
  1094.         SetGadgetAttrs
  1095.         (   iff_gadgets[GID_6_ST3],
  1096.             MainWindowPtr, NULL,
  1097.             STRINGA_TextVal, "-",
  1098.             TAG_END
  1099.         );
  1100.     } else
  1101.     {   iff.cd           = form[selectedform].flags & CD;
  1102.         iff.rkm          = form[selectedform].flags & RKM;
  1103.         iff.private      = form[selectedform].flags & PRIVATE;
  1104.         iff.proposal     = form[selectedform].flags & PROPOSAL;
  1105.         iff.obsolete     = form[selectedform].flags & OBSOLETE;
  1106.         iff.reserved     = form[selectedform].flags & RESERVED;
  1107.         iff.standard     = form[selectedform].flags & STANDARD;
  1108.         iff.unregistered = form[selectedform].flags & UNREGISTERED;
  1109.  
  1110.         SetGadgetAttrs
  1111.         (   iff_gadgets[GID_6_ST2],
  1112.             MainWindowPtr, NULL,
  1113.             STRINGA_TextVal, form[selectedform].desc,
  1114.             TAG_END
  1115.         );
  1116.         SetGadgetAttrs
  1117.         (   iff_gadgets[GID_6_ST3],
  1118.             MainWindowPtr, NULL,
  1119.             STRINGA_TextVal, form[selectedform].contributor,
  1120.             TAG_END
  1121.         );
  1122.     }
  1123.  
  1124.     writeiffgadgets();
  1125.  
  1126.     SetGadgetAttrs
  1127.     (   iff_gadgets[GID_6_LB1],
  1128.         MainWindowPtr, NULL,
  1129.         LISTBROWSER_Labels, NULL, // detach it
  1130.         TAG_END
  1131.     );
  1132.     clearreactionlist(&List1);
  1133.  
  1134.     SetGadgetAttrs
  1135.     (   iff_gadgets[GID_6_LB2],
  1136.         MainWindowPtr, NULL,
  1137.         LISTBROWSER_Labels, NULL, // detach it
  1138.         TAG_END
  1139.     );
  1140.     clearreactionlist(&List2);
  1141.  
  1142.     for (i = 0; i < items; i++)
  1143.     {   if (contents[i].DataPtr)
  1144.         {   FreeMem(contents[i].DataPtr, contents[i].bytes);
  1145.             contents[i].DataPtr = NULL;
  1146.     }   }
  1147.     items = 0;
  1148. }
  1149.  
  1150. MODULE void readiff(void)
  1151. {   LONG error;
  1152.  
  1153.     iffquery();
  1154.  
  1155.     /* Allocate IFF_File structure. */
  1156.     if (!(IFFHandle = AllocIFF()))
  1157.     {   DisplayBeep(NULL);
  1158.         SetGadgetAttrs
  1159.         (   iff_gadgets[GID_6_ST5],
  1160.             MainWindowPtr, NULL,
  1161.             STRINGA_TextVal, "AllocIFF() failed!",
  1162.             TAG_END
  1163.         );
  1164.  
  1165.         goto bye;
  1166.     }
  1167.  
  1168.     first = TRUE;
  1169.  
  1170.     /* Set up IFF_File for AmigaDOS I/O.  */
  1171.     if (!(IFFHandle->iff_Stream = Open(iff.pathname, MODE_OLDFILE)))
  1172.     {   DisplayBeep(NULL);
  1173.         SetGadgetAttrs
  1174.         (   iff_gadgets[GID_6_ST5],
  1175.             MainWindowPtr, NULL,
  1176.             STRINGA_TextVal, "Can't open file!",
  1177.             TAG_END
  1178.         );
  1179.         SetGadgetAttrs
  1180.         (   iff_gadgets[GID_6_ST2],
  1181.             MainWindowPtr, NULL,
  1182.             STRINGA_TextVal, "-",
  1183.             TAG_END
  1184.         );
  1185.         SetGadgetAttrs
  1186.         (   iff_gadgets[GID_6_ST3],
  1187.             MainWindowPtr, NULL,
  1188.             STRINGA_TextVal, "-",
  1189.             TAG_END
  1190.         );
  1191.  
  1192.         queryform[0]     = 0;
  1193.         iff.obsolete     =
  1194.         iff.private      =
  1195.         iff.proposal     =
  1196.         iff.reserved     =
  1197.         iff.standard     =
  1198.         iff.unregistered =
  1199.         iff.rkm          =
  1200.         iff.cd           = FALSE;
  1201.         writeiffgadgets();
  1202.         goto bye;
  1203.     }
  1204.     InitIFFasDOS(IFFHandle);
  1205.  
  1206.     /* Start the IFF transaction. */
  1207.     if (error = OpenIFF(IFFHandle, IFFF_READ))
  1208.     {   DisplayBeep(NULL);
  1209.         SetGadgetAttrs
  1210.         (   iff_gadgets[GID_6_ST5],
  1211.             MainWindowPtr, NULL,
  1212.             STRINGA_TextVal, "OpenIFF() failed!",
  1213.             TAG_END
  1214.         );
  1215.         goto bye;
  1216.     }
  1217.  
  1218.     while (1)
  1219.     {   /* IFFPARSE_RAWSTEP permits us to have precision monitoring of the
  1220.          * parsing process, which is necessary if we wish to print the
  1221.          * structure of an IFF file.
  1222.          *   ParseIFF() with _RAWSTEP will return the following things for
  1223.          * the following reasons:
  1224.          *
  1225.          * Return code:                 Reason:
  1226.          * 0                            Entered new context.
  1227.          * IFFERR_EOC                   About to leave a context.
  1228.          * IFFERR_EOF                   Encountered end-of-file.
  1229.          * <anything else>              A parsing error.
  1230.          */
  1231.         error = ParseIFF(IFFHandle, IFFPARSE_RAWSTEP);
  1232.  
  1233.         /*
  1234.          * Since we're only interested in when we enter a context, we
  1235.          * "discard" end-of-context (_EOC) events.
  1236.          */
  1237.         if (error == IFFERR_EOC)
  1238.             continue;
  1239.         elif (error)
  1240.         {   // Leave the loop if there is any other error.
  1241.             break;
  1242.         }
  1243.  
  1244.         /* If we get here, error was zero. Print out the current state of
  1245.          * affairs. */
  1246.         PrintTopChunk();
  1247.     }
  1248.  
  1249.     /* If error was IFFERR_EOF, then the parser encountered the end of
  1250.      * the file without problems. Otherwise, we print a diagnostic.
  1251.      */
  1252.     if (error == IFFERR_EOF)
  1253.     {   SetGadgetAttrs
  1254.         (   iff_gadgets[GID_6_ST5],
  1255.             MainWindowPtr, NULL,
  1256.             STRINGA_TextVal, "Ready.",
  1257.             TAG_END
  1258.         );
  1259.         SetGadgetAttrs
  1260.         (   iff_gadgets[GID_6_LB1],
  1261.             MainWindowPtr, NULL,
  1262.             LISTBROWSER_Labels, &List1,
  1263.             TAG_END
  1264.         );
  1265.     } else
  1266.     {   SetGadgetAttrs
  1267.         (   iff_gadgets[GID_6_ST5],
  1268.             MainWindowPtr, NULL,
  1269.             STRINGA_TextVal, errormsgs[-error - 1],
  1270.             TAG_END
  1271.         );
  1272.         SetGadgetAttrs
  1273.         (   iff_gadgets[GID_6_LB1],
  1274.             MainWindowPtr, NULL,
  1275.             LISTBROWSER_Labels, NULL, // detach it
  1276.             TAG_END
  1277.         );
  1278.     }
  1279.  
  1280. bye:
  1281.     if (IFFHandle)
  1282.     {   /* Terminate the IFF transaction with the stream. Free all
  1283.          * associated structures. */
  1284.         CloseIFF(IFFHandle);
  1285.         // Close the stream itself.
  1286.         if (IFFHandle->iff_Stream)
  1287.         {   Close(IFFHandle->iff_Stream);
  1288.         }
  1289.         // Free the IFF_File structure itself.
  1290.         FreeIFF(IFFHandle);
  1291.         IFFHandle = NULL;
  1292. }   }
  1293.  
  1294. AGLOBAL void iff_exit(void)
  1295. {   ULONG i;
  1296.  
  1297.     if (IFFHandle)
  1298.     {   /* Terminate the IFF transaction with the stream. Free all
  1299.          * associated structures. */
  1300.         CloseIFF(IFFHandle);
  1301.         // Close the stream itself.
  1302.         if (IFFHandle->iff_Stream)
  1303.         {   Close(IFFHandle->iff_Stream);
  1304.         }
  1305.         // Free the IFF_File structure itself.
  1306.         FreeIFF(IFFHandle);
  1307.         IFFHandle = NULL;
  1308.     }
  1309.  
  1310.     clearreactionlist(&List2);
  1311.     clearreactionlist(&List1);
  1312.  
  1313.     for (i = 0; i < items; i++)
  1314.     {   if (contents[i].DataPtr)
  1315.         {   FreeMem(contents[i].DataPtr, contents[i].bytes);
  1316.             contents[i].DataPtr = NULL;
  1317.     }   }
  1318.     items = 0;
  1319. }
  1320.  
  1321. MODULE void PrintTopChunk(void)
  1322. {   struct ContextNode* top;
  1323.     short               i;
  1324.     char                idbuf[5];
  1325.     ULONG               length;
  1326.  
  1327.     /* Get a pointer to the context node describing the current context. */
  1328.     if (!(top = CurrentChunk(IFFHandle)))
  1329.         return;
  1330.  
  1331.     /* Print spaces equivalent to the current nesting depth of chunks
  1332.      * processed so far.
  1333.      *   This will cause nested chunks to be printed out indented. */
  1334.  
  1335.     tempstring1[0] = 0;
  1336.     if (IFFHandle->iff_Depth > 2)
  1337.     {   for (i = IFFHandle->iff_Depth - 2; i--; )
  1338.            strcat(tempstring1, " ");
  1339.     }
  1340.     strcpy(contents[items].name, IDtoStr(top->cn_ID, idbuf));
  1341.     contents[items].DataPtr = NULL;
  1342.  
  1343.     /* Print out the current chunk's ID and size. */
  1344.     strcat(tempstring1, IDtoStr(top->cn_ID, idbuf));
  1345.     stcl_d(tempstring2, top->cn_Size);
  1346.  
  1347.     length = IFFXCHARS - strlen(tempstring1) - strlen(tempstring2);
  1348.     for (i = 1; i <= length; i++)
  1349.     {   strcat(tempstring1, " ");
  1350.     }
  1351.     strcat(tempstring1, tempstring2);
  1352.  
  1353.     /* Print the current chunk's type, with a newline. */
  1354.     addreactionnode(&List1, tempstring1);
  1355.  
  1356.     if (!strcmp(IDtoStr(top->cn_ID, idbuf), "FORM"))
  1357.     {   if (first)
  1358.         {   first = FALSE;
  1359.             strcpy(queryform, IDtoStr(top->cn_Type, idbuf));
  1360.             iffquery();
  1361.     }   }
  1362.     else
  1363.     {   contents[items].bytes = top->cn_Size;
  1364.         if (!(contents[items].DataPtr = AllocMem(contents[items].bytes, MEMF_CLEAR)))
  1365.         {   rq("Out of memory!");
  1366.         }
  1367.         if (ReadChunkBytes(IFFHandle, contents[items].DataPtr, contents[items].bytes) < 0)
  1368.         {   rq("ReadChunkBytes() failed!");
  1369.     }   }
  1370.  
  1371.     items++;
  1372.     if (items > ITEMS)
  1373.     {   rq("Too many chunks!");
  1374. }   }
  1375.  
  1376. MODULE void tellchunk(UWORD which)
  1377. {   SLONG           svalue;
  1378.     ULONG           i, j, uvalue, length, markers, currentpos;
  1379.     struct DateTime DateTime;
  1380.  
  1381.     if (which == (UWORD) ~0)
  1382.     {   return;
  1383.     }
  1384.  
  1385.     SetGadgetAttrs
  1386.     (   iff_gadgets[GID_6_LB2],
  1387.         MainWindowPtr, NULL,
  1388.         LISTBROWSER_Labels, NULL, // detach it
  1389.         TAG_END
  1390.     );
  1391.     clearreactionlist(&List2);
  1392.     known = FALSE;
  1393.  
  1394.     if (!stricmp(contents[which].name, "FORM"))
  1395.     {   chunkdesc("-", TRUE);
  1396.     } elif (!stricmp(contents[which].name, "(c) "))
  1397.     {   chunkdesc("© Copyright", TRUE);
  1398.  
  1399.         if (!iff.raw)
  1400.         {   label("© Copyright:");
  1401.             strcat(tempstring1, contents[which].DataPtr);
  1402.             addreactionnode(&List2, tempstring1);
  1403.     }   }
  1404.     elif (!stricmp(contents[which].name, "AUTH"))
  1405.     {   chunkdesc("Author", TRUE);
  1406.  
  1407.         if (!iff.raw)
  1408.         {   label("Author:");
  1409.             strcat(tempstring1, contents[which].DataPtr);
  1410.             addreactionnode(&List2, tempstring1);
  1411.     }   }
  1412.     elif (!stricmp(contents[which].name, "ANNO"))
  1413.     {   chunkdesc("Annotation", TRUE);
  1414.  
  1415.         if (!iff.raw)
  1416.         {   label("Annotation:");
  1417.             strcat(tempstring1, contents[which].DataPtr);
  1418.             addreactionnode(&List2, tempstring1);
  1419.     }   }
  1420.     elif (!stricmp(contents[which].name, "NAME"))
  1421.     {   chunkdesc("Name", TRUE);
  1422.  
  1423.         if (!iff.raw)
  1424.         {   label("Name:");
  1425.             strcat(tempstring1, contents[which].DataPtr);
  1426.             addreactionnode(&List2, tempstring1);
  1427.     }   }
  1428.     elif (!stricmp(contents[which].name, "FVER"))
  1429.     {   chunkdesc("AmigaDOS version string", TRUE);
  1430.  
  1431.         if (!iff.raw)
  1432.         {   label("Version:");
  1433.             // bytes 0-5 are "$VER: "
  1434.             strcat(tempstring1, &contents[which].DataPtr[6]);
  1435.             addreactionnode(&List2, tempstring1);
  1436.     }   }
  1437.     elif
  1438.     (   (!stricmp(queryform, "FTXT") || !stricmp(queryform, "WORD"))
  1439.      && !stricmp(contents[which].name, "FSCC")
  1440.     )
  1441.     {   chunkdesc("Font/style/colour change", TRUE);
  1442.  
  1443.         if (!iff.raw)
  1444.         {   label("Location:");
  1445.             uvalue = getuword(contents[which].DataPtr); // UWORD
  1446.             unumcat(uvalue, TRUE);
  1447.  
  1448.             label("Font number:");
  1449.             uvalue = contents[which].DataPtr[2]; // UBYTE
  1450.             unumcat(uvalue, TRUE);
  1451.  
  1452.             label("Style:");
  1453.             addreactionnode(&List2, tempstring1);
  1454.  
  1455.             label(" Underlined?");
  1456.             dobool(contents[which].DataPtr[3] & 1);
  1457.  
  1458.             label(" Bold?");
  1459.             dobool(contents[which].DataPtr[3] & 2);
  1460.  
  1461.             label(" Italic?");
  1462.             dobool(contents[which].DataPtr[3] & 4);
  1463.  
  1464.             label(" Extended?");
  1465.             dobool(contents[which].DataPtr[3] & 8);
  1466.  
  1467.             label(" ColourFont?");
  1468.             dobool(contents[which].DataPtr[3] & 64);
  1469.  
  1470.             label(" Tagged?");
  1471.             dobool(contents[which].DataPtr[3] & 128);
  1472.  
  1473.             label("Miscellaneous style:");
  1474.             interpret(1, (ULONG) contents[which].DataPtr[4]);
  1475.  
  1476.             label("Colour:");
  1477.             uvalue = contents[which].DataPtr[5]; // UBYTE
  1478.             unumcat(uvalue, TRUE);
  1479.     }   }
  1480.     elif (!strcmp(queryform, "FTXT"))
  1481.     {   if (!strcmp(contents[which].name, "FONS"))
  1482.         {   chunkdesc("Font specifier", TRUE);
  1483.  
  1484.         if (!iff.raw)
  1485.         {
  1486.             label("ID number:");
  1487.             snumcat((SLONG) contents[which].DataPtr[0], FALSE);
  1488.             if (contents[which].DataPtr[0] > 9)
  1489.             {   strcat(tempstring1, " (invalid)");
  1490.             }
  1491.             addreactionnode(&List2, tempstring1);
  1492.  
  1493.             // Next is a pad byte ([1]).
  1494.  
  1495.             label("Proportional?");
  1496.             interpret(2, (ULONG) contents[which].DataPtr[2]);
  1497.  
  1498.             label("Serifs?");
  1499.             interpret(2, (ULONG) contents[which].DataPtr[3]);
  1500.  
  1501.             label("Font name:");
  1502.             strcat(tempstring1, &(contents[which].DataPtr[4]));
  1503.             addreactionnode(&List2, tempstring1);
  1504.         }   }
  1505.         elif (!strcmp(contents[which].name, "CHRS"))
  1506.         {   chunkdesc("Stream of text", FALSE);
  1507.     }   }
  1508.     elif (!strcmp(queryform, "PREF"))
  1509.     {   if (!strcmp(contents[which].name, "ICTL"))
  1510.         {   chunkdesc("IControl preferences", TRUE);
  1511.  
  1512.         if (!iff.raw)
  1513.         {
  1514.             label("Verify timeout:");
  1515.             uvalue = getuword(&(contents[which].DataPtr[16]));
  1516.             unumcat(uvalue, TRUE);
  1517.  
  1518.             label("Meta drag mouse event:");
  1519.             svalue = getsword(&(contents[which].DataPtr[18]));
  1520.             snumcat(svalue, TRUE);
  1521.  
  1522.             addreactionnode(&List2, "Flags:");
  1523.             uvalue = getulong(&(contents[which].DataPtr[20]));
  1524.  
  1525.             label(" Coerce colours?");
  1526.             dobool((UBYTE) (uvalue & 1)); // ICF_COERCE_COLORS
  1527.  
  1528.             label(" Coerce interlace?");
  1529.             dobool((UBYTE) (uvalue & 2)); // ICF_COERCE_LACE
  1530.  
  1531.             label(" String gadget filter?");
  1532.             dobool((UBYTE) (uvalue & 4)); // ICF_STRGAD_FILTER
  1533.  
  1534.             label(" Menu snap?");
  1535.             dobool((UBYTE) (uvalue & 8)); // ICF_MENUSNAP
  1536.  
  1537.             label(" Mode promotion?");
  1538.             dobool((UBYTE) (uvalue & 16)); // ICF_MODEPROMOTE
  1539.  
  1540.             label(" Square ratio?"); // this one is new for OS3.9
  1541.             dobool((UBYTE) (uvalue & 32)); // ICF_SQUARE_RATIO
  1542.  
  1543.             addreactionnode(&List2, "Command keys:");
  1544.  
  1545.             label(" Workbench to front:");
  1546.             snumcat((SLONG) contents[which].DataPtr[24], TRUE);
  1547.  
  1548.             label(" Front screen to back:");
  1549.             snumcat((SLONG) contents[which].DataPtr[25], TRUE);
  1550.  
  1551.             label(" Requester TRUE:");
  1552.             snumcat((SLONG) contents[which].DataPtr[26], TRUE);
  1553.  
  1554.             label(" Requester FALSE:");
  1555.             snumcat((SLONG) contents[which].DataPtr[27], TRUE);
  1556.         }   }
  1557.         elif (!strcmp(contents[which].name, "SERL"))
  1558.         {   chunkdesc("Serial preferences", TRUE);
  1559.  
  1560.         if (!iff.raw)
  1561.         {
  1562.             label("Unit 0 mapping:");
  1563.             uvalue = getulong(&(contents[which].DataPtr[12]));
  1564.             unumcat(uvalue, TRUE);
  1565.  
  1566.             label("Baud rate:");
  1567.             uvalue = getulong(&(contents[which].DataPtr[16]));
  1568.             unumcat(uvalue, FALSE);
  1569.             strcat(tempstring1, " bps");
  1570.             addreactionnode(&List2, tempstring1);
  1571.  
  1572.             label("Input buffer size:");
  1573.             uvalue = getulong(&(contents[which].DataPtr[20]));
  1574.             unumcat(uvalue, FALSE);
  1575.             if (uvalue > 65536)
  1576.             {   strcat(tempstring1, "!");
  1577.             }
  1578.             addreactionnode(&List2, tempstring1);
  1579.  
  1580.             label("Output buffer size:");
  1581.             uvalue = getulong(&(contents[which].DataPtr[24]));
  1582.             unumcat(uvalue, FALSE);
  1583.             if (uvalue > 65536)
  1584.             {   strcat(tempstring1, "!");
  1585.             }
  1586.             addreactionnode(&List2, tempstring1);
  1587.  
  1588.             label("Input handshaking:");
  1589.             interpret(0, (ULONG) contents[which].DataPtr[28]);
  1590.  
  1591.             label("Output handshaking:");
  1592.             interpret(0, (ULONG) contents[which].DataPtr[29]);
  1593.  
  1594.             label("Parity:");
  1595.             interpret(3, (ULONG) contents[which].DataPtr[30]);
  1596.  
  1597.             label("I/O bits per character:");
  1598.             snumcat((SLONG) contents[which].DataPtr[31], TRUE);
  1599.  
  1600.             label("Stop bits:");
  1601.             snumcat((SLONG) contents[which].DataPtr[32], TRUE);
  1602.         }   }
  1603.         elif (!strcmp(contents[which].name, "ASL "))
  1604.         {   chunkdesc("ASL preferences", TRUE);
  1605.  
  1606.             // 16 reserved bytes at start
  1607.  
  1608.             if (!iff.raw)
  1609.             {   label("Sort by:");
  1610.                 interpret(4, (ULONG) contents[which].DataPtr[16]);
  1611.  
  1612.                 label("Sort drawers:");
  1613.                 interpret(5, (ULONG) contents[which].DataPtr[17]);
  1614.  
  1615.                 label("Sort order:");
  1616.                 interpret(6, (ULONG) contents[which].DataPtr[18]);
  1617.  
  1618.                 label("Override?");
  1619.                 dobool(contents[which].DataPtr[19] & 64);
  1620.  
  1621.                 label("Relative?");
  1622.                 dobool(contents[which].DataPtr[19] & 16);
  1623.  
  1624.                 label("Position:");
  1625.                 interpret(7, (ULONG) contents[which].DataPtr[19] & 16);
  1626.  
  1627.                 label("Left edge:");
  1628.                 svalue = getsword(&(contents[which].DataPtr[20]));
  1629.                 snumcat(svalue, TRUE);
  1630.  
  1631.                 label("Top edge:");
  1632.                 svalue = getsword(&(contents[which].DataPtr[22]));
  1633.                 snumcat(svalue, TRUE);
  1634.  
  1635.                 label("Relative width:");
  1636.                 snumcat((SLONG) contents[which].DataPtr[24], FALSE);
  1637.                 if (contents[which].DataPtr[24] < 25 || contents[which].DataPtr[24] > 100)
  1638.                 {   strcat(tempstring1, "!");
  1639.                 }
  1640.                 strcat(tempstring1, "%");
  1641.                 addreactionnode(&List2, tempstring1);
  1642.  
  1643.                 label("Relative height:");
  1644.                 snumcat((SLONG) contents[which].DataPtr[25], FALSE);
  1645.                 if (contents[which].DataPtr[25] < 25 || contents[which].DataPtr[25] > 100)
  1646.                 {   strcat(tempstring1, "!");
  1647.                 }
  1648.                 strcat(tempstring1, "%");
  1649.                 addreactionnode(&List2, tempstring1);
  1650.         }   }
  1651.         elif (!strcmp(contents[which].name, "FONT"))
  1652.         {   chunkdesc("Font preferences", TRUE);
  1653.  
  1654.             // 14 reserved bytes at start
  1655.  
  1656.         if (!iff.raw)
  1657.         {
  1658.             label("Type:");
  1659.             uvalue = getuword(&(contents[which].DataPtr[14]));
  1660.             interpret(8, uvalue);
  1661.  
  1662.             label("Front pen:");
  1663.             snumcat((SLONG) contents[which].DataPtr[16], TRUE);
  1664.  
  1665.             label("Back pen:");
  1666.             snumcat((SLONG) contents[which].DataPtr[17], TRUE);
  1667.  
  1668.             label("Draw mode:");
  1669.             interpret(9, (ULONG) contents[which].DataPtr[18]);
  1670.  
  1671.             /* Now we have an undocumented pad byte, necessary for
  1672.             structure alignment purposes. */
  1673.  
  1674.             addreactionnode(&List2, "Text attributes:");
  1675.  
  1676.             dotextattr(&contents[which].DataPtr[20]);
  1677.  
  1678.             label("Name:");
  1679.             strcat(tempstring1, &(contents[which].DataPtr[28]));
  1680.             addreactionnode(&List2, tempstring1);
  1681.         }   }
  1682.         elif (!strcmp(contents[which].name, "INPT"))
  1683.         {   chunkdesc("Input preferences", TRUE);
  1684.  
  1685.             // The first 16 bytes are a keymap, currently ignored
  1686.  
  1687.         if (!iff.raw)
  1688.         {
  1689.             label("Pointer sensitivity:");
  1690.             uvalue = getuword(&(contents[which].DataPtr[16]));
  1691.             unumcat(uvalue, FALSE);
  1692.             strcat(tempstring1, " ticks");
  1693.             addreactionnode(&List2, tempstring1);
  1694.  
  1695.             addreactionnode(&List2, "Double-click interval:");
  1696.  
  1697.             label(" Seconds:");
  1698.             uvalue = getulong(&(contents[which].DataPtr[18]));
  1699.             unumcat(uvalue, TRUE);
  1700.  
  1701.             label(" Microseconds:");
  1702.             uvalue = getulong(&(contents[which].DataPtr[22]));
  1703.             unumcat(uvalue, TRUE);
  1704.  
  1705.             addreactionnode(&List2, "Key repeat delay:");
  1706.  
  1707.             label(" Seconds:");
  1708.             uvalue = getulong(&(contents[which].DataPtr[26]));
  1709.             unumcat(uvalue, TRUE);
  1710.  
  1711.             label(" Microseconds:");
  1712.             uvalue = getulong(&(contents[which].DataPtr[30]));
  1713.             unumcat(uvalue, TRUE);
  1714.  
  1715.             addreactionnode(&List2, "Key repeat speed:");
  1716.  
  1717.             label(" Seconds:");
  1718.             uvalue = getulong(&(contents[which].DataPtr[34]));
  1719.             unumcat(uvalue, TRUE);
  1720.  
  1721.             label(" Microseconds:");
  1722.             uvalue = getulong(&(contents[which].DataPtr[38]));
  1723.             unumcat(uvalue, TRUE);
  1724.  
  1725.             label("Mouse acceleration:");
  1726.             svalue = getsword(&(contents[which].DataPtr[42]));
  1727.             snumcat(svalue, TRUE);
  1728.         }   }
  1729.         elif (!strcmp(contents[which].name, "OSCN"))
  1730.         {   chunkdesc("Overscan preferences", TRUE);
  1731.  
  1732.         if (!iff.raw)
  1733.         {
  1734.             label("Magic?");
  1735.             uvalue = getulong(&(contents[which].DataPtr[4]));
  1736.             if (uvalue == 0xFEDCBA89) // OSCAN_MAGIC
  1737.             {   strcat(tempstring1, "Yes");
  1738.             } else
  1739.             {   strcat(tempstring1, "No");
  1740.             }
  1741.             addreactionnode(&List2, tempstring1);
  1742.  
  1743.             label("Horizontal start:");
  1744.             uvalue = getuword(&(contents[which].DataPtr[8]));
  1745.             unumcat(uvalue, TRUE);
  1746.  
  1747.             label("Horizontal stop:");
  1748.             uvalue = getuword(&(contents[which].DataPtr[10]));
  1749.             unumcat(uvalue, TRUE);
  1750.  
  1751.             label("Vertical start:");
  1752.             uvalue = getuword(&(contents[which].DataPtr[12]));
  1753.             unumcat(uvalue, TRUE);
  1754.  
  1755.             label("Vertical stop:");
  1756.             uvalue = getuword(&(contents[which].DataPtr[14]));
  1757.             unumcat(uvalue, TRUE);
  1758.  
  1759.             label("DisplayID:");
  1760.             uvalue = getulong(&(contents[which].DataPtr[16]));
  1761.             unumcat(uvalue, TRUE);
  1762.  
  1763.             label("View offset:");
  1764.             svalue = getsword(&(contents[which].DataPtr[20]));
  1765.             snumcat(svalue, FALSE);
  1766.             strcat(tempstring1, ",");
  1767.             svalue = getsword(&(contents[which].DataPtr[22]));
  1768.             snumcat(svalue, TRUE);
  1769.  
  1770.             label("Text overscan size:");
  1771.             svalue = getsword(&(contents[which].DataPtr[24]));
  1772.             snumcat(svalue, FALSE);
  1773.             strcat(tempstring1, ",");
  1774.             svalue = getsword(&(contents[which].DataPtr[26]));
  1775.             snumcat(svalue, TRUE);
  1776.  
  1777.             addreactionnode(&List2, "Standard overscan size:");
  1778.  
  1779.             label(" Top-left corner:");
  1780.             svalue = getsword(&(contents[which].DataPtr[28]));
  1781.             snumcat(svalue, FALSE);
  1782.             strcat(tempstring1, ",");
  1783.             svalue = getsword(&(contents[which].DataPtr[30]));
  1784.             snumcat(svalue, TRUE);
  1785.  
  1786.             label(" Bottom-right corner:");
  1787.             svalue = getsword(&(contents[which].DataPtr[32]));
  1788.             snumcat(svalue, FALSE);
  1789.             strcat(tempstring1, ",");
  1790.             svalue = getsword(&(contents[which].DataPtr[34]));
  1791.             snumcat(svalue, TRUE);
  1792.         }   }
  1793.         elif (!strcmp(contents[which].name, "SCRM"))
  1794.         {   chunkdesc("Screen mode preferences", TRUE);
  1795.  
  1796.         if (!iff.raw)
  1797.         {
  1798.             label("DisplayID:");
  1799.             uvalue = getulong(&(contents[which].DataPtr[16]));
  1800.             unumcat(uvalue, TRUE);
  1801.  
  1802.             label("Screen width:");
  1803.             uvalue = getuword(&(contents[which].DataPtr[20]));
  1804.             unumcat(uvalue, TRUE);
  1805.  
  1806.             label("Screen height:");
  1807.             uvalue = getuword(&(contents[which].DataPtr[22]));
  1808.             unumcat(uvalue, TRUE);
  1809.  
  1810.             label("Screen depth:");
  1811.             uvalue = getuword(&(contents[which].DataPtr[24]));
  1812.             unumcat(uvalue, TRUE);
  1813.  
  1814.             label("Autoscroll?");
  1815.             uvalue = getuword(&(contents[which].DataPtr[26]));
  1816.             dobool((UBYTE) (uvalue & 1)); // SMB_AUTOSCROLL
  1817.         }   }
  1818.         elif (!strcmp(contents[which].name, "PSPD"))
  1819.         {   chunkdesc("PostScript printer preferences", TRUE);
  1820.  
  1821.         if (!iff.raw)
  1822.         {   addreactionnode(&List2, "Global attributes:");
  1823.  
  1824.             label(" Driver mode:");
  1825.             interpret(10, (ULONG) contents[which].DataPtr[16]);
  1826.  
  1827.             label(" Paper format:");
  1828.             interpret(11, (ULONG) contents[which].DataPtr[17]);
  1829.  
  1830.             // now two reserved bytes
  1831.  
  1832.             label(" Copies:");
  1833.             svalue = getslong(&(contents[which].DataPtr[20]));
  1834.             snumcat(svalue, TRUE);
  1835.  
  1836.             label(" Paper width:");
  1837.             svalue = getslong(&(contents[which].DataPtr[24]));
  1838.             snumcat(svalue, FALSE);
  1839.             strcat(tempstring1, " millipoints");
  1840.             addreactionnode(&List2, tempstring1);
  1841.  
  1842.             label(" Paper height:");
  1843.             svalue = getslong(&(contents[which].DataPtr[28]));
  1844.             snumcat(svalue, FALSE);
  1845.             strcat(tempstring1, " millipoints");
  1846.             addreactionnode(&List2, tempstring1);
  1847.  
  1848.             label(" Horizontal DPI:");
  1849.             svalue = getslong(&(contents[which].DataPtr[32]));
  1850.             snumcat(svalue, FALSE);
  1851.             strcat(tempstring1, " millipoints");
  1852.             addreactionnode(&List2, tempstring1);
  1853.  
  1854.             label(" Vertical DPI:");
  1855.             svalue = getslong(&(contents[which].DataPtr[36]));
  1856.             snumcat(svalue, FALSE);
  1857.             strcat(tempstring1, " millipoints");
  1858.             addreactionnode(&List2, tempstring1);
  1859.  
  1860.             addreactionnode(&List2, "Text options:");
  1861.  
  1862.             label(" Font:");
  1863.             interpret(12, (ULONG) contents[which].DataPtr[40]);
  1864.  
  1865.             label(" Pitch:");
  1866.             interpret(13, (ULONG) contents[which].DataPtr[41]);
  1867.  
  1868.             label(" Orientation:");
  1869.             interpret(14, (ULONG) contents[which].DataPtr[42]);
  1870.  
  1871.             label(" Tab stops:");
  1872.             interpret(15, (ULONG) contents[which].DataPtr[43]);
  1873.  
  1874.             // now eight reserved bytes
  1875.  
  1876.             addreactionnode(&List2, "Text dimensions:");
  1877.  
  1878.             label(" Left margin:");
  1879.             svalue = getslong(&(contents[which].DataPtr[52]));
  1880.             snumcat(svalue, FALSE);
  1881.             strcat(tempstring1, " millipoints");
  1882.             addreactionnode(&List2, tempstring1);
  1883.  
  1884.             label(" Right margin:");
  1885.             svalue = getslong(&(contents[which].DataPtr[56]));
  1886.             snumcat(svalue, FALSE);
  1887.             strcat(tempstring1, " millipoints");
  1888.             addreactionnode(&List2, tempstring1);
  1889.  
  1890.             label(" Top margin:");
  1891.             svalue = getslong(&(contents[which].DataPtr[60]));
  1892.             snumcat(svalue, FALSE);
  1893.             strcat(tempstring1, " millipoints");
  1894.             addreactionnode(&List2, tempstring1);
  1895.  
  1896.             label(" Bottom margin:");
  1897.             svalue = getslong(&(contents[which].DataPtr[64]));
  1898.             snumcat(svalue, FALSE);
  1899.             strcat(tempstring1, " millipoints");
  1900.             addreactionnode(&List2, tempstring1);
  1901.  
  1902.             label(" Font size:");
  1903.             svalue = getslong(&(contents[which].DataPtr[68]));
  1904.             snumcat(svalue, FALSE);
  1905.             strcat(tempstring1, " millipoints");
  1906.             addreactionnode(&List2, tempstring1);
  1907.  
  1908.             label(" Leading:");
  1909.             svalue = getslong(&(contents[which].DataPtr[72]));
  1910.             snumcat(svalue, FALSE);
  1911.             strcat(tempstring1, " millipoints");
  1912.             addreactionnode(&List2, tempstring1);
  1913.  
  1914.             // now eight reserved bytes
  1915.  
  1916.             addreactionnode(&List2, "Graphics options:");
  1917.  
  1918.             label(" Left edge:");
  1919.             svalue = getslong(&(contents[which].DataPtr[80]));
  1920.             snumcat(svalue, FALSE);
  1921.             strcat(tempstring1, " millipoints");
  1922.             addreactionnode(&List2, tempstring1);
  1923.  
  1924.             label(" Top edge:");
  1925.             svalue = getslong(&(contents[which].DataPtr[84]));
  1926.             snumcat(svalue, FALSE);
  1927.             strcat(tempstring1, " millipoints");
  1928.             addreactionnode(&List2, tempstring1);
  1929.  
  1930.             label(" Width:");
  1931.             svalue = getslong(&(contents[which].DataPtr[88]));
  1932.             snumcat(svalue, FALSE);
  1933.             strcat(tempstring1, " millipoints");
  1934.             addreactionnode(&List2, tempstring1);
  1935.  
  1936.             label(" Height:");
  1937.             svalue = getslong(&(contents[which].DataPtr[92]));
  1938.             snumcat(svalue, FALSE);
  1939.             strcat(tempstring1, " millipoints");
  1940.             addreactionnode(&List2, tempstring1);
  1941.  
  1942.             label(" Image:");
  1943.             interpret(16, (ULONG) contents[which].DataPtr[96]);
  1944.  
  1945.             label(" Shading:");
  1946.             interpret(17, (ULONG) contents[which].DataPtr[97]);
  1947.  
  1948.             label(" Dithering:");
  1949.             interpret(18, (ULONG) contents[which].DataPtr[98]);
  1950.  
  1951.             // now nine reserved bytes
  1952.  
  1953.             addreactionnode(&List2, "Graphics scaling:");
  1954.  
  1955.             label(" Aspect:");
  1956.             interpret(19, (ULONG) contents[which].DataPtr[108]);
  1957.  
  1958.             label(" Scaling type:");
  1959.             interpret(20, (ULONG) contents[which].DataPtr[109]);
  1960.  
  1961.             // now one reserved byte
  1962.  
  1963.             label(" Centering:");
  1964.             interpret(21, (ULONG) contents[which].DataPtr[111]);
  1965.         }   }
  1966.         elif (!strcmp(contents[which].name, "PGFX"))
  1967.         {   chunkdesc("Printer graphics preferences", TRUE);
  1968.  
  1969.         if (!iff.raw)
  1970.         {
  1971.             label("Aspect:");
  1972.             uvalue = getuword(&(contents[which].DataPtr[16]));
  1973.             interpret(19, uvalue);
  1974.  
  1975.             label("Shading:");
  1976.             uvalue = getuword(&(contents[which].DataPtr[18]));
  1977.             interpret(22, uvalue);
  1978.  
  1979.             label("Image:");
  1980.             uvalue = getuword(&(contents[which].DataPtr[20]));
  1981.             interpret(16, uvalue);
  1982.  
  1983.             label("Threshold:");
  1984.             svalue = getsword(&(contents[which].DataPtr[22]));
  1985.             snumcat(svalue, TRUE);
  1986.  
  1987.             addreactionnode(&List2, "Colour correction:");
  1988.  
  1989.             label(" Red?");
  1990.             dobool(contents[which].DataPtr[24] & 1); // PCCF_RED
  1991.  
  1992.             label(" Green?");
  1993.             dobool(contents[which].DataPtr[24] & 2); // PCCF_GREEN
  1994.  
  1995.             label(" Blue?");
  1996.             dobool(contents[which].DataPtr[24] & 4); // PCCF_BLUE
  1997.  
  1998.             label("Dimensions:");
  1999.             interpret(23, (ULONG) contents[which].DataPtr[25]);
  2000.  
  2001.             label("Dithering:");
  2002.             interpret(24, (ULONG) contents[which].DataPtr[26]);
  2003.  
  2004.             label("Flags:");
  2005.             addreactionnode(&List2, tempstring1);
  2006.  
  2007.             uvalue = getuword(&(contents[which].DataPtr[27]));
  2008.  
  2009.             label(" Centre image?");
  2010.             dobool((UBYTE) (uvalue & 1)); // PGFF_CENTER_IMAGE
  2011.  
  2012.             label(" Integer scaling?");
  2013.             dobool((UBYTE) (uvalue & 2)); // PGFF_INTEGER_SCALING
  2014.  
  2015.             label(" Antialiasing?");
  2016.             dobool((UBYTE) (uvalue & 4)); // PGFF_ANTI_ALIAS
  2017.  
  2018.             label("Print density:");
  2019.             snumcat((SLONG) contents[which].DataPtr[29], FALSE);
  2020.             if (contents[which].DataPtr[29] < 1 || contents[which].DataPtr[29] > 7)
  2021.             {   strcat(tempstring1, "!");
  2022.             }
  2023.             addreactionnode(&List2, tempstring1);
  2024.  
  2025.             label("Maximum width:");
  2026.             uvalue = getuword(&(contents[which].DataPtr[30]));
  2027.             unumcat(uvalue, TRUE);
  2028.  
  2029.             label("Maximum height:");
  2030.             uvalue = getuword(&(contents[which].DataPtr[32]));
  2031.             unumcat(uvalue, TRUE);
  2032.  
  2033.             label("Offset:");
  2034.             snumcat((SLONG) contents[which].DataPtr[34], FALSE);
  2035.             strcat(tempstring1, ",");
  2036.             snumcat((SLONG) contents[which].DataPtr[35], TRUE);
  2037.         }   }
  2038.         elif (!strcmp(contents[which].name, "PTXT"))
  2039.         {   chunkdesc("Printer text preferences", TRUE);
  2040.  
  2041.         if (!iff.raw)
  2042.         {
  2043.             label("Driver filename:");
  2044.             strcat(tempstring1, &(contents[which].DataPtr[16]));
  2045.             // 32-character field, so it doesn't need truncation
  2046.             addreactionnode(&List2, tempstring1);
  2047.  
  2048.             label("Port:");
  2049.             interpret(25, (ULONG) contents[which].DataPtr[48]);
  2050.  
  2051.             label("Paper type:");
  2052.             uvalue = getuword(&(contents[which].DataPtr[49]));
  2053.             interpret(26, uvalue);
  2054.  
  2055.             label("Paper size:");
  2056.             uvalue = getuword(&(contents[which].DataPtr[51]));
  2057.             interpret(27, uvalue);
  2058.  
  2059.             label("Paper length:");
  2060.             uvalue = getuword(&(contents[which].DataPtr[53]));
  2061.             unumcat(uvalue, FALSE);
  2062.             strcat(tempstring1, " lines");
  2063.             addreactionnode(&List2, tempstring1);
  2064.  
  2065.             label("Pitch:");
  2066.             uvalue = getuword(&(contents[which].DataPtr[55]));
  2067.             interpret(28, uvalue);
  2068.  
  2069.             label("Spacing:");
  2070.             uvalue = getuword(&(contents[which].DataPtr[57]));
  2071.             interpret(29, uvalue);
  2072.  
  2073.             label("Left margin:");
  2074.             uvalue = getuword(&(contents[which].DataPtr[59]));
  2075.             unumcat(uvalue, TRUE);
  2076.  
  2077.             label("Right margin:");
  2078.             uvalue = getuword(&(contents[which].DataPtr[61]));
  2079.             unumcat(uvalue, TRUE);
  2080.  
  2081.             label("Quality:");
  2082.             uvalue = getuword(&(contents[which].DataPtr[63]));
  2083.             interpret(30, uvalue);
  2084.         }   }
  2085.         elif (!strcmp(contents[which].name, "SOND"))
  2086.         {   chunkdesc("Sound preferences", TRUE);
  2087.  
  2088.             // 16 reserved bytes at start
  2089.  
  2090.         if (!iff.raw)
  2091.         {   label("Flash display?");
  2092.             uvalue = getuword(&contents[which].DataPtr[16]); // BOOL
  2093.             dobool((UBYTE) uvalue);
  2094.  
  2095.             label("Make sounds?");
  2096.             uvalue = getuword(&contents[which].DataPtr[18]); // BOOL
  2097.             dobool((UBYTE) uvalue);
  2098.  
  2099.             label("Type of sound:");
  2100.             uvalue = getuword(&contents[which].DataPtr[20]); // UWORD
  2101.             interpret(31, uvalue);
  2102.  
  2103.             label("Volume:");
  2104.             uvalue = getuword(&contents[which].DataPtr[22]); // uword
  2105.             unumcat(uvalue, FALSE);
  2106.             if (uvalue > 64)
  2107.             {   strcat(tempstring1, "!");
  2108.             }
  2109.             strcat(tempstring1, "/64");
  2110.             addreactionnode(&List2, tempstring1);
  2111.  
  2112.             label("Period:");
  2113.             uvalue = getuword(&contents[which].DataPtr[24]); // uword
  2114.             unumcat(uvalue, FALSE);
  2115.             if (uvalue < 127 || uvalue > 2500)
  2116.             {   strcat(tempstring1, "!");
  2117.             }
  2118.             addreactionnode(&List2, tempstring1);
  2119.  
  2120.             label("Beep length:");
  2121.             uvalue = getuword(&contents[which].DataPtr[26]); // uword
  2122.             unumcat(uvalue, TRUE);
  2123.  
  2124.             label("Sample filename:");
  2125.             strcat(tempstring1, &contents[which].DataPtr[28]); // 256 chars
  2126.             addreactionnode(&List2, tempstring1);
  2127.         }   }
  2128.         elif (!strcmp(contents[which].name, "PTRN"))
  2129.         {   chunkdesc("Workbench pattern preferences", TRUE);
  2130.  
  2131.             // 16 reserved bytes at start
  2132.  
  2133.         if (!iff.raw)
  2134.         {
  2135.             label("Which pattern?");
  2136.             uvalue = getuword(&contents[which].DataPtr[16]); // UWORD
  2137.             interpret(32, uvalue);
  2138.  
  2139.             uvalue = getuword(&contents[which].DataPtr[18]); // UWORD
  2140.  
  2141.             label("Data contains pattern?");
  2142.             dobool((UBYTE) (uvalue & 1)); // WBPF_PATTERN
  2143.  
  2144.             label("Remap pattern?"); // note that this one is inverted
  2145.             if (uvalue & 16) // WBPF_NOREMAP
  2146.             {   strcat(tempstring1, "No");
  2147.             } else
  2148.             {   strcat(tempstring1, "Yes");
  2149.             }
  2150.             addreactionnode(&List2, tempstring1);
  2151.  
  2152.             label("Dither quality:");
  2153.             if (uvalue & 768) // these comparisons are order-dependent
  2154.             {   strcat(tempstring1, "Best");
  2155.             } elif (uvalue & 512)
  2156.             {   strcat(tempstring1, "Good");
  2157.             } elif (uvalue & 256)
  2158.             {   strcat(tempstring1, "Poor");
  2159.             } else
  2160.             {   strcat(tempstring1, "Default");
  2161.             }
  2162.             addreactionnode(&List2, tempstring1);
  2163.  
  2164.             label("Colour quality:");
  2165.             if (uvalue & 3072) // these comparisons are order-dependent
  2166.             {   strcat(tempstring1, "Best");
  2167.             } elif (uvalue & 2048)
  2168.             {   strcat(tempstring1, "Good");
  2169.             } elif (uvalue & 1024)
  2170.             {   strcat(tempstring1, "Poor");
  2171.             } else
  2172.             {   strcat(tempstring1, "Default");
  2173.             }
  2174.             addreactionnode(&List2, tempstring1);
  2175.  
  2176.             label("Layout:");
  2177.             if (uvalue & 12288) // these comparisons are order-dependent
  2178.             {   strcat(tempstring1, "Scale well");
  2179.             } elif (uvalue & 8192)
  2180.             {   strcat(tempstring1, "Scale");
  2181.             } elif (uvalue & 4096)
  2182.             {   strcat(tempstring1, "Centre");
  2183.             } else
  2184.             {   strcat(tempstring1, "Tile");
  2185.             }
  2186.             addreactionnode(&List2, tempstring1);
  2187.  
  2188.             label("Revision:"); // BYTE
  2189.             snumcat((SLONG) contents[which].DataPtr[20], TRUE);
  2190.  
  2191.             label("Pattern depth:"); // BYTE
  2192.             snumcat((SLONG) contents[which].DataPtr[21], TRUE);
  2193.  
  2194.             label("Data length:"); // UWORD
  2195.             uvalue = getuword(&contents[which].DataPtr[22]);
  2196.             unumcat(uvalue, TRUE);
  2197.         }   }
  2198.         elif (!strcmp(contents[which].name, "PNTR"))
  2199.         {   chunkdesc("Pointer preferences", TRUE);
  2200.  
  2201.             // 16 reserved bytes at start
  2202.  
  2203.         if (!iff.raw)
  2204.         {   label("Which pointer?");
  2205.             uvalue = getuword(&contents[which].DataPtr[16]); // UWORD
  2206.             interpret(33, uvalue);
  2207.  
  2208.             label("Horizontal size:");
  2209.             uvalue = getuword(&contents[which].DataPtr[18]); // UWORD
  2210.             interpret(34, uvalue);
  2211.  
  2212.             label("Width:");
  2213.             uvalue = getuword(&contents[which].DataPtr[20]); // UWORD
  2214.             unumcat(uvalue, FALSE);
  2215.             strcat(tempstring1, " pixels");
  2216.             addreactionnode(&List2, tempstring1);
  2217.  
  2218.             label("Height:");
  2219.             uvalue = getuword(&contents[which].DataPtr[22]); // UWORD
  2220.             unumcat(uvalue, FALSE);
  2221.             strcat(tempstring1, " pixels");
  2222.             addreactionnode(&List2, tempstring1);
  2223.  
  2224.             label("Depth:");
  2225.             uvalue = getuword(&contents[which].DataPtr[24]); // UWORD
  2226.             unumcat(uvalue, FALSE);
  2227.             strcat(tempstring1, " planes");
  2228.             addreactionnode(&List2, tempstring1);
  2229.  
  2230.             label("Vertical size:");
  2231.             uvalue = getuword(&contents[which].DataPtr[26]); // UWORD
  2232.             interpret(35, uvalue);
  2233.  
  2234.             label("Hotspot coordinates:");
  2235.             uvalue = getuword(&contents[which].DataPtr[28]); // UWORD
  2236.             unumcat(uvalue, FALSE);
  2237.             strcat(tempstring1, ",");
  2238.             uvalue = getuword(&contents[which].DataPtr[30]); // UWORD
  2239.             unumcat(uvalue, TRUE);
  2240.         }   }
  2241.         elif (!strcmp(contents[which].name, "PALT")) // ignored
  2242.         {   chunkdesc("Palette preferences", FALSE);
  2243.         } elif (!strcmp(contents[which].name, "AHIG"))
  2244.         {   chunkdesc("AHI global preferences", TRUE);
  2245.  
  2246.             if (!iff.raw)
  2247.             {   label("Debug level:");
  2248.                 uvalue = getuword(contents[which].DataPtr); // UWORD
  2249.                 interpret(36, uvalue);
  2250.  
  2251.                 label("Disable surround sound?");
  2252.                 uvalue = getuword(&contents[which].DataPtr[2]); // BOOL
  2253.                 dobool((UBYTE) uvalue);
  2254.  
  2255.                 label("Disable echo?");
  2256.                 uvalue = getuword(&contents[which].DataPtr[4]); // BOOL
  2257.                 dobool((UBYTE) uvalue);
  2258.  
  2259.                 label("Fast echo?");
  2260.                 uvalue = getuword(&contents[which].DataPtr[6]); // BOOL
  2261.                 dobool((UBYTE) uvalue);
  2262.  
  2263.                 label("Maximum CPU usage:");
  2264.                 svalue = getslong(&(contents[which].DataPtr[8]));
  2265.                 svalue /= 1024; // LONG (Fixed)
  2266.                 snumcat(svalue, FALSE);
  2267.                 strcat(tempstring1, "/64");
  2268.                 addreactionnode(&List2, tempstring1);
  2269.  
  2270.                 label("Clip master volume?");
  2271.                 uvalue = getuword(&contents[which].DataPtr[12]); // BOOL
  2272.                 dobool((UBYTE) uvalue);
  2273.         }   }
  2274.         elif (!strcmp(contents[which].name, "AHIU"))
  2275.         {   chunkdesc("AHI unit preferences", TRUE);
  2276.  
  2277.             if (!iff.raw)
  2278.             {   label("Unit:");
  2279.                 snumcat((SLONG) contents[which].DataPtr[0], TRUE); // UBYTE
  2280.  
  2281.                 // byte 1 is a pad byte
  2282.  
  2283.                 label("Channels:");
  2284.                 uvalue = getuword(&contents[which].DataPtr[2]); // UWORD
  2285.                 unumcat(uvalue, TRUE);
  2286.  
  2287.                 label("Audio mode:");
  2288.                 uvalue = getuword(&contents[which].DataPtr[4]); // ULONG
  2289.                 unumcat(uvalue, TRUE); // perhaps this can be interpreted?
  2290.  
  2291.                 label("Frequency:");
  2292.                 uvalue = getuword(&contents[which].DataPtr[8]); // ULONG
  2293.                 unumcat(uvalue, TRUE);
  2294.  
  2295.                 label("Monitor volume:");
  2296.                 svalue = getslong(&(contents[which].DataPtr[12]));
  2297.                 svalue /= 1024; // LONG (Fixed)
  2298.                 snumcat(svalue, FALSE);
  2299.                 strcat(tempstring1, "/64");
  2300.                 addreactionnode(&List2, tempstring1);
  2301.  
  2302.                 label("Input gain:");
  2303.                 svalue = getslong(&(contents[which].DataPtr[16]));
  2304.                 svalue /= 1024; // LONG (Fixed)
  2305.                 snumcat(svalue, FALSE);
  2306.                 strcat(tempstring1, "/64");
  2307.                 addreactionnode(&List2, tempstring1);
  2308.  
  2309.                 label("Output volume:");
  2310.                 svalue = getslong(&(contents[which].DataPtr[20]));
  2311.                 svalue /= 1024; // LONG (Fixed)
  2312.                 snumcat(svalue, FALSE);
  2313.                 strcat(tempstring1, "/64");
  2314.                 addreactionnode(&List2, tempstring1);
  2315.  
  2316.                 label("Input:");
  2317.                 uvalue = getuword(&contents[which].DataPtr[24]); // ULONG
  2318.                 unumcat(uvalue, TRUE); // perhaps this can be interpreted?
  2319.  
  2320.                 label("Output:");
  2321.                 uvalue = getuword(&contents[which].DataPtr[28]); // ULONG
  2322.                 unumcat(uvalue, TRUE); // perhaps this can be interpreted?
  2323.         }   }
  2324.         elif (!strcmp(contents[which].name, "WBNC"))
  2325.         {   chunkdesc("Workbench preferences", TRUE);
  2326.  
  2327.         if (!iff.raw)
  2328.         {
  2329.             label("Default stack size:");
  2330.             uvalue = getulong(contents[which].DataPtr); // ULONG
  2331.             unumcat(uvalue, FALSE);
  2332.             strcat(tempstring1, " bytes");
  2333.             addreactionnode(&List2, tempstring1);
  2334.  
  2335.             label("Type restart time:");
  2336.             uvalue = getulong(&contents[which].DataPtr[4]); // ULONG
  2337.             unumcat(uvalue, FALSE);
  2338.             strcat(tempstring1, " seconds");
  2339.             addreactionnode(&List2, tempstring1);
  2340.  
  2341.             label("Icon precision:");
  2342.             uvalue = getulong(&contents[which].DataPtr[8]); // ULONG
  2343.             if (uvalue == (ULONG) -1) // PRECISION_EXACT
  2344.             {   strcat(tempstring1, "-1 (exact)");
  2345.             } elif (uvalue == 0) // PRECISION_IMAGE
  2346.             {   strcat(tempstring1, "0 (image)");
  2347.             } elif (uvalue == 16) // PRECISION_ICON
  2348.             {   strcat(tempstring1, "16 (icon)");
  2349.             } elif (uvalue == 32) // PRECISION_GUI
  2350.             {   strcat(tempstring1, "32 (GUI)");
  2351.             } else
  2352.             {   strcat(tempstring1, "?");
  2353.             }
  2354.             addreactionnode(&List2, tempstring1);
  2355.  
  2356.             addreactionnode(&List2, "Emboss rectangle:");
  2357.  
  2358.             label(" Top-left corner:");
  2359.             svalue = getsword(&contents[which].DataPtr[12]); // WORD
  2360.             snumcat(svalue, FALSE);
  2361.             strcat(tempstring1, ",");
  2362.             svalue = getuword(&contents[which].DataPtr[14]); // WORD
  2363.             snumcat(svalue, TRUE);
  2364.  
  2365.             label(" Bottom-right corner:");
  2366.             svalue = getsword(&contents[which].DataPtr[16]); // WORD
  2367.             snumcat(svalue, FALSE);
  2368.             strcat(tempstring1, ",");
  2369.             svalue = getuword(&contents[which].DataPtr[18]); // WORD
  2370.             snumcat(svalue, TRUE);
  2371.  
  2372.             label("Borderless?");
  2373.             uvalue = getuword(&contents[which].DataPtr[20]); // BOOL
  2374.             dobool((UBYTE) uvalue);
  2375.  
  2376.             label("Max. filename length:");
  2377.             svalue = getslong(&contents[which].DataPtr[22]); // LONG
  2378.             snumcat(svalue, FALSE);
  2379.             strcat(tempstring1, " characters");
  2380.             addreactionnode(&List2, tempstring1);
  2381.  
  2382.             label("NewIcons support?");
  2383.             uvalue = getuword(&contents[which].DataPtr[26]); // BOOL
  2384.             dobool((UBYTE) uvalue);
  2385.  
  2386.             label("ColourIcons support?");
  2387.             uvalue = getuword(&contents[which].DataPtr[28]); // BOOL
  2388.             dobool((UBYTE) uvalue);
  2389.  
  2390.             // remainder of these are new for OS3.9
  2391.  
  2392.             if (contents[which].bytes > 30)
  2393.             {   label("Image memory type:");
  2394.                 uvalue = getulong(&contents[which].DataPtr[30]); // ULONG
  2395.                 if (uvalue == 1)
  2396.                 {   strcat(tempstring1, "1 (Other memory)");
  2397.                 } elif (uvalue == 2)
  2398.                 {   strcat(tempstring1, "2 (Graphics (chip) memory)");
  2399.                 } else
  2400.                 {   strcat(tempstring1, "?");
  2401.                 }
  2402.                 addreactionnode(&List2, tempstring1);
  2403.  
  2404.                 label("Lock pens?");
  2405.                 uvalue = getuword(&contents[which].DataPtr[34]); // BOOL
  2406.                 dobool((UBYTE) uvalue);
  2407.  
  2408.                 label("Title bar?"); // this one is inverted
  2409.                 uvalue = getuword(&contents[which].DataPtr[36]); // BOOL
  2410.                 if (uvalue)
  2411.                 {   strcat(tempstring1, "No");
  2412.                 } else
  2413.                 {   strcat(tempstring1, "Yes");
  2414.                 }
  2415.                 addreactionnode(&List2, tempstring1);
  2416.  
  2417.                 label("Volume gauge?"); // this one is inverted
  2418.                 uvalue = getuword(&contents[which].DataPtr[38]); // BOOL
  2419.                 if (uvalue)
  2420.                 {   strcat(tempstring1, "No");
  2421.                 } else
  2422.                 {   strcat(tempstring1, "Yes");
  2423.                 }
  2424.                 addreactionnode(&List2, tempstring1);
  2425.         }   }   }
  2426.         elif (!strcmp(contents[which].name, "WBHD"))
  2427.         {   chunkdesc("Workbench hidden device preferences", TRUE);
  2428.  
  2429.             if (!iff.raw)
  2430.             {   label("Name:");
  2431.                 strcat(tempstring1, contents[which].DataPtr);
  2432.                 addreactionnode(&List2, tempstring1);
  2433.         }   }
  2434.         elif (!strcmp(contents[which].name, "LCLE"))
  2435.         {   chunkdesc("Locale preferences", TRUE);
  2436.  
  2437.             // 16 reserved bytes at start
  2438.  
  2439.         if (!iff.raw)
  2440.         {   label("Country name:");
  2441.             strcat(tempstring1, &contents[which].DataPtr[16]); // 32 chars
  2442.             addreactionnode(&List2, tempstring1);
  2443.  
  2444.             label("Preferred languages:");
  2445.             addreactionnode(&List2, tempstring1);
  2446.  
  2447.             for (i = 1; i <= 10; i++)
  2448.             {   strcpy(tempstring3, " ");
  2449.                 if (i < 10)
  2450.                 {   strcat(tempstring3, " ");
  2451.                 }
  2452.                 stcl_d(tempstring2, i);
  2453.                 strcat(tempstring3, tempstring2);
  2454.                 strcat(tempstring3, ":");
  2455.                 label(tempstring3);
  2456.                 strcat(tempstring1, &contents[which].DataPtr[48 + ((i - 1) * 30)]); // 10 entries of 30 chars each
  2457.                 addreactionnode(&List2, tempstring1);
  2458.             }
  2459.  
  2460.             label("Time from GMT:");
  2461.             svalue = getslong(&contents[which].DataPtr[348]); // LONG
  2462.             snumcat(svalue, FALSE);
  2463.             strcat(tempstring1, " minutes");
  2464.             addreactionnode(&List2, tempstring1);
  2465.  
  2466.             label("Flags:");
  2467.             uvalue = getulong(&contents[which].DataPtr[352]); // ULONG
  2468.             unumcat(uvalue, TRUE);
  2469.  
  2470.             docountry(&contents[which].DataPtr[356]);
  2471.         }   }
  2472.         elif (!strcmp(contents[which].name, "CTRY"))
  2473.         {   chunkdesc("Country preferences", TRUE);
  2474.  
  2475.             if (!iff.raw)
  2476.             {   docountry(contents[which].DataPtr);
  2477.         }   }
  2478.         elif (!strcmp(contents[which].name, "RACT"))
  2479.         {   chunkdesc("ReAction preferences", TRUE);
  2480.  
  2481.         if (!iff.raw)
  2482.         {
  2483.             label("Bevel type:"); // UWORD
  2484.             uvalue = getuword(contents[which].DataPtr);
  2485.             interpret(37, uvalue);
  2486.  
  2487.             label("Glyph type:"); // UWORD
  2488.             uvalue = getuword(&contents[which].DataPtr[2]);
  2489.             interpret(38, uvalue);
  2490.  
  2491.             label("Layout spacing:"); // UWORD
  2492.             uvalue = getuword(&contents[which].DataPtr[4]);
  2493.             unumcat(uvalue, TRUE);
  2494.  
  2495.             label("3D Proportional?");
  2496.             uvalue = getuword(&contents[which].DataPtr[6]); // BOOL
  2497.             dobool((UBYTE) uvalue);
  2498.  
  2499.             label("Label pen:"); // UWORD
  2500.             uvalue = getuword(&contents[which].DataPtr[8]);
  2501.             unumcat(uvalue, TRUE);
  2502.  
  2503.             label("Label placement:"); // UWORD
  2504.             uvalue = getuword(&contents[which].DataPtr[10]);
  2505.             /* This has been reverse-engineered
  2506.             using the ReAction preferences editor */
  2507.             interpret(39, uvalue);
  2508.  
  2509.             label("3D Label?");
  2510.             uvalue = getuword(&contents[which].DataPtr[12]); // BOOL
  2511.             dobool((UBYTE) uvalue);
  2512.  
  2513.             label("Refreshing Method:");
  2514.             uvalue = getuword(&contents[which].DataPtr[14]); // BOOL
  2515.             if (uvalue)
  2516.             {   strcat(tempstring1, "Simple");
  2517.             } else
  2518.             {   strcat(tempstring1, "Smart");
  2519.             }
  2520.             addreactionnode(&List2, tempstring1);
  2521.  
  2522.             label("3D Look?");
  2523.             uvalue = getuword(&contents[which].DataPtr[16]); // BOOL
  2524.             dobool((UBYTE) uvalue);
  2525.  
  2526.             addreactionnode(&List2, "Fallback font:");
  2527.             dotextattr(&contents[which].DataPtr[18]); // struct TextAttr (8 bytes)
  2528.             addreactionnode(&List2, "Label font:");
  2529.             dotextattr(&contents[which].DataPtr[26]); // struct TextAttr (8 bytes)
  2530.  
  2531.             label("Fallback font name:");
  2532.             strcat(tempstring1, &contents[which].DataPtr[34]); // 128 UBYTEs
  2533.             addreactionnode(&List2, tempstring1);
  2534.  
  2535.             label("Label font name:");
  2536.             strcat(tempstring1, &contents[which].DataPtr[162]); // 128 UBYTEs
  2537.             addreactionnode(&List2, tempstring1);
  2538.  
  2539.             label("Backdrop pattern:");
  2540.             strcat(tempstring1, &contents[which].DataPtr[290]); // 256 UBYTEs
  2541.             addreactionnode(&List2, tempstring1);
  2542.         }   }
  2543.         elif (!strcmp(contents[which].name, "PRHD"))
  2544.         {   chunkdesc("Preferences header", TRUE);
  2545.  
  2546.         if (!iff.raw)
  2547.         {   label("Version:");
  2548.             snumcat((SLONG) contents[which].DataPtr[0], TRUE);
  2549.                                
  2550.             label("Type:");
  2551.             snumcat((SLONG) contents[which].DataPtr[1], TRUE);
  2552.  
  2553.             label("Flags:");
  2554.             uvalue = getuword(&(contents[which].DataPtr[2]));
  2555.             unumcat(uvalue, TRUE);
  2556.     }   }   }
  2557.     elif (!strcmp(queryform, "SMUS"))
  2558.     {   if (!strcmp(contents[which].name, "SHDR"))
  2559.         {   chunkdesc("Global information for the score", TRUE);
  2560.  
  2561.         if (!iff.raw)
  2562.         {
  2563.             label("Tempo:");
  2564.             uvalue = getuword(contents[which].DataPtr);
  2565.             uvalue /= 128;
  2566.             unumcat(uvalue, FALSE);
  2567.             strcat(tempstring1, " bpm");
  2568.             addreactionnode(&List2, tempstring1);
  2569.  
  2570.             label("Volume:");
  2571.             snumcat((SLONG) contents[which].DataPtr[2], FALSE);
  2572.             strcat(tempstring1, "/127");
  2573.             addreactionnode(&List2, tempstring1);
  2574.  
  2575.             label("Tracks:");
  2576.             snumcat((SLONG) contents[which].DataPtr[3], TRUE);
  2577.         }   }
  2578.         elif (!strcmp(contents[which].name, "INS1"))
  2579.         {   chunkdesc("Identifies an instrument to use", TRUE);
  2580.  
  2581.         if (!iff.raw)
  2582.         {
  2583.             label("Register number:");
  2584.             snumcat((SLONG) contents[which].DataPtr[0], TRUE); // UBYTE
  2585.  
  2586.             label("Reference type:");
  2587.             interpret(40, (ULONG) contents[which].DataPtr[1]); // UBYTE
  2588.  
  2589.             label("MIDI channel:");
  2590.             if (contents[which].DataPtr[1] == 1) // if find on MIDI
  2591.             {   snumcat((SLONG) contents[which].DataPtr[2], TRUE); // UBYTE
  2592.             } else
  2593.             {   strcat(tempstring1, "n/a");
  2594.                 addreactionnode(&List2, tempstring1);
  2595.             }
  2596.  
  2597.             label("MIDI preset:");
  2598.             if (contents[which].DataPtr[1] == 1) // if find on MIDI
  2599.             {   snumcat((SLONG) contents[which].DataPtr[3], TRUE);
  2600.             } else
  2601.             {   strcat(tempstring1, "n/a");
  2602.                 addreactionnode(&List2, tempstring1);
  2603.             }
  2604.  
  2605.             label("Instrument name:");
  2606.             strcat(tempstring1, (STRPTR) contents[which].DataPtr + 4); // STRPTR
  2607.             addreactionnode(&List2, tempstring1);
  2608.         }   }
  2609.         elif (!strcmp(contents[which].name, "TRAK"))
  2610.         {   chunkdesc("Linear stream of events", FALSE);
  2611.         } elif (!strcmp(contents[which].name, "INST"))
  2612.         {   chunkdesc("Obsolete; use INS1 instead", FALSE);
  2613.         } elif (!stricmp(contents[which].name, "IRev")) // this could also perhaps be IREV
  2614.         {   chunkdesc("Instant Music private chunk", FALSE);
  2615.         } elif (!strcmp(contents[which].name, "BIAS"))
  2616.         {   chunkdesc("Instant Music private chunk", FALSE);
  2617.     }   }
  2618.     elif (!strcmp(queryform, "HEAD"))
  2619.     {   if (!strcmp(contents[which].name, "NEST"))
  2620.         {   chunkdesc("Nesting level", TRUE);
  2621.  
  2622.             if (!iff.raw)
  2623.             {   label("Nesting level:");
  2624.                 uvalue = getuword(contents[which].DataPtr);
  2625.                 unumcat(uvalue, TRUE);
  2626.         }   }
  2627.         elif (!strcmp(contents[which].name, "TEXT"))
  2628.         {   chunkdesc("Heading text", FALSE);
  2629.     }   }
  2630.     elif (!strcmp(queryform, "WORD"))
  2631.     {   if (!strcmp(contents[which].name, "FONT"))
  2632.         {   chunkdesc("Font name/number table", TRUE);
  2633.  
  2634.             if (!iff.raw)
  2635.             {   label("Number:");
  2636.                 snumcat((SLONG) contents[which].DataPtr[0], TRUE); // UBYTE
  2637.  
  2638.                 label("Size:");
  2639.                 uvalue = getuword(&contents[which].DataPtr[1]);
  2640.                 unumcat(uvalue, TRUE);
  2641.  
  2642.                 label("Name:");
  2643.                 strcat(tempstring1, &contents[which].DataPtr[3]);
  2644.                 addreactionnode(&List2, tempstring1);
  2645.         }   }
  2646.         elif (!strcmp(contents[which].name, "COLR"))
  2647.         {   chunkdesc("Colour translation table", TRUE);
  2648.  
  2649.             if (!iff.raw)
  2650.             {   for (i = 0; i <= 7; i++)
  2651.                 {   strcpy(tempstring3, "Colour ");
  2652.                     stcl_d(tempstring2, i);
  2653.                     strcat(tempstring3, tempstring2);
  2654.                     strcat(tempstring3, ":");
  2655.                     label(tempstring3);
  2656.                     snumcat((SLONG) contents[which].DataPtr[i], TRUE);
  2657.         }   }   }
  2658.         elif (!strcmp(contents[which].name, "DOC "))
  2659.         {   chunkdesc("Begin document section", TRUE);
  2660.  
  2661.             if (!iff.raw)
  2662.             {   label("Starting page:");
  2663.                 uvalue = getuword(contents[which].DataPtr);
  2664.                 unumcat(uvalue, TRUE);
  2665.  
  2666.                 label("Numbering style:");
  2667.                 interpret(41, (ULONG) contents[which].DataPtr[2]);
  2668.         }   }
  2669.         elif (!strcmp(contents[which].name, "HEAD"))
  2670.         {   chunkdesc("Begin header section", TRUE);
  2671.  
  2672.             if (!iff.raw)
  2673.             {   label("Page type:");
  2674.                 interpret(42, (ULONG) contents[which].DataPtr[0]);
  2675.  
  2676.                 label("First page?");
  2677.                 dobool(contents[which].DataPtr[1]);
  2678.         }   }
  2679.         elif (!strcmp(contents[which].name, "FOOT"))
  2680.         {   chunkdesc("Begin footer section", TRUE);
  2681.  
  2682.             if (!iff.raw)
  2683.             {   label("Page type:");
  2684.                 interpret(42, (ULONG) contents[which].DataPtr[0]);
  2685.  
  2686.                 label("First page?");
  2687.                 dobool(contents[which].DataPtr[1]);
  2688.         }   }
  2689.         elif (!strcmp(contents[which].name, "PCTS"))
  2690.         {   chunkdesc("Begin picture section", TRUE);
  2691.  
  2692.             if (!iff.raw)
  2693.             {   label("Bitplanes:");
  2694.                 snumcat((SLONG) contents[which].DataPtr[0], TRUE); // UBYTE
  2695.         }   }
  2696.         elif (!strcmp(contents[which].name, "PARA"))
  2697.         {   chunkdesc("New paragraph format", TRUE);
  2698.  
  2699.         if (!iff.raw)
  2700.         {   label("Left indent:");
  2701.             uvalue = getuword(contents[which].DataPtr); // UWORD
  2702.             unumcat(uvalue, FALSE);
  2703.             strcat(tempstring1, " decipoints");
  2704.             addreactionnode(&List2, tempstring1);
  2705.  
  2706.             label("Left margin:");
  2707.             uvalue = getuword(&(contents[which].DataPtr[2])); // UWORD
  2708.             unumcat(uvalue, FALSE);
  2709.             strcat(tempstring1, " decipoints");
  2710.             addreactionnode(&List2, tempstring1);
  2711.  
  2712.             label("Right margin:");
  2713.             uvalue = getuword(&(contents[which].DataPtr[4])); // UWORD
  2714.             unumcat(uvalue, FALSE);
  2715.             strcat(tempstring1, " decipoints");
  2716.             addreactionnode(&List2, tempstring1);
  2717.  
  2718.             label("Line spacing:");
  2719.             if (contents[which].DataPtr[6] == 0)
  2720.             {   strcat(tempstring1, "Single");
  2721.             } elif (contents[which].DataPtr[6] == 16)
  2722.             {   strcat(tempstring1, "Double");
  2723.             } else
  2724.             {   strcat(tempstring1, "?");
  2725.             }
  2726.             addreactionnode(&List2, tempstring1);
  2727.  
  2728.             label("Justification:");
  2729.             interpret(43, (ULONG) contents[which].DataPtr[7]);
  2730.  
  2731.             label("Font number:");
  2732.             uvalue = contents[which].DataPtr[8]; // UBYTE
  2733.             unumcat(uvalue, TRUE);
  2734.  
  2735.             addreactionnode(&List2, " Style:");
  2736.  
  2737.             label(" Underlined?");
  2738.             dobool(contents[which].DataPtr[9] & 1);
  2739.  
  2740.             label(" Bold?");
  2741.             dobool(contents[which].DataPtr[9] & 2);
  2742.  
  2743.             label(" Italic?");
  2744.             dobool(contents[which].DataPtr[9] & 4);
  2745.  
  2746.             label(" Extended?");
  2747.             dobool(contents[which].DataPtr[9] & 8);
  2748.  
  2749.             label(" ColourFont?");
  2750.             dobool(contents[which].DataPtr[9] & 64);
  2751.  
  2752.             label(" Tagged?");
  2753.             dobool(contents[which].DataPtr[9] & 128);
  2754.  
  2755.             label("Miscellaneous style:");
  2756.             interpret(1, (ULONG) contents[which].DataPtr[10]);
  2757.  
  2758.             label("Colour:");
  2759.             uvalue = contents[which].DataPtr[11]; // UBYTE
  2760.             unumcat(uvalue, TRUE);
  2761.         }   }
  2762.         elif (!strcmp(contents[which].name, "TABS"))
  2763.         {   chunkdesc("New tab stop types/locations", TRUE);
  2764.  
  2765.             if (!iff.raw)
  2766.             {   label("Position:");
  2767.                 uvalue = getuword(contents[which].DataPtr); // UWORD
  2768.                 unumcat(uvalue, FALSE);
  2769.                 strcat(tempstring1, " decipoints");
  2770.                 addreactionnode(&List2, tempstring1);
  2771.  
  2772.                 label("Type:");
  2773.                 interpret(44, (ULONG) contents[which].DataPtr[2]);
  2774.         }   }
  2775.         elif (!strcmp(contents[which].name, "PAGE"))
  2776.         {   chunkdesc("Page break", FALSE);
  2777.         } elif (!strcmp(contents[which].name, "TEXT"))
  2778.         {   chunkdesc("Paragraph text", FALSE);
  2779.         } elif (!strcmp(contents[which].name, "PINF"))
  2780.         {   chunkdesc("Picture info", TRUE);
  2781.  
  2782.         if (!iff.raw)
  2783.         {   label("Width:");
  2784.             uvalue = getuword(contents[which].DataPtr); // UWORD
  2785.             unumcat(uvalue, TRUE);
  2786.  
  2787.             label("Height:");
  2788.             uvalue = getuword(&(contents[which].DataPtr[2])); // UWORD
  2789.             unumcat(uvalue, TRUE);
  2790.  
  2791.             label("Page:");
  2792.             uvalue = getuword(&(contents[which].DataPtr[4])); // UWORD
  2793.             unumcat(uvalue, TRUE);
  2794.  
  2795.             label("X-position:");
  2796.             uvalue = getuword(&(contents[which].DataPtr[6])); // UWORD
  2797.             unumcat(uvalue, FALSE);
  2798.             strcat(tempstring1, " decipoints");
  2799.             addreactionnode(&List2, tempstring1);
  2800.  
  2801.             label("Y-position:");
  2802.             uvalue = getuword(&(contents[which].DataPtr[8])); // UWORD
  2803.             unumcat(uvalue, FALSE);
  2804.             strcat(tempstring1, " decipoints");
  2805.             addreactionnode(&List2, tempstring1);
  2806.  
  2807.             label("Masking:");
  2808.             interpret(45, (ULONG) contents[which].DataPtr[10]);
  2809.  
  2810.             label("Compression:");
  2811.             interpret(46, (ULONG) contents[which].DataPtr[11]);
  2812.  
  2813.             label("Transparent colour:");
  2814.             if (contents[which].DataPtr[10] != 2
  2815.              && contents[which].DataPtr[10] != 3)
  2816.             {   strcat(tempstring1, "n/a");
  2817.                 addreactionnode(&List2, tempstring1);
  2818.             } else
  2819.             {   uvalue = getuword(&(contents[which].DataPtr[12])); // UWORD
  2820.                 unumcat(uvalue, TRUE);
  2821.             }
  2822.     }   }   }
  2823.     elif (!strcmp(queryform, "AIFF"))
  2824.     {   if (!strcmp(contents[which].name, "MIDI"))
  2825.         {   chunkdesc("Stores MIDI data", FALSE);
  2826.         } elif (!strcmp(contents[which].name, "MARK"))
  2827.         {   chunkdesc("Points to positions in the sound data", TRUE);
  2828.  
  2829.         if (!iff.raw)
  2830.         {   label("Markers:");
  2831.  
  2832.             svalue = getsword(contents[which].DataPtr);
  2833.             snumcat(svalue, FALSE);
  2834.             if (svalue < 0)
  2835.             {   strcat(tempstring1, "!");
  2836.             }
  2837.             addreactionnode(&List2, tempstring1);
  2838.             markers = svalue;
  2839.             if (markers > 0)
  2840.             {   currentpos = 2;
  2841.                 for (i = 1; i <= markers; i++)
  2842.                 {   strcpy(tempstring3, "Marker ");
  2843.                     stcl_d(tempstring2, i);
  2844.                     strcat(tempstring3, tempstring2);
  2845.                     strcat(tempstring3, ":");
  2846.                     label(tempstring3);
  2847.                     addreactionnode(&List2, tempstring1);
  2848.  
  2849.                     label(" ID:");
  2850.                     svalue = getsword(&(contents[which].name[currentpos]));
  2851.                     snumcat(svalue, FALSE);
  2852.                     if (svalue < 1)
  2853.                     {   strcat(tempstring1, "!");
  2854.                     }
  2855.                     addreactionnode(&List2, tempstring1);
  2856.                     currentpos += 2;
  2857.  
  2858.                     label(" Position:");
  2859.                     uvalue = getulong(&(contents[which].name[currentpos]));
  2860.                     unumcat(uvalue, TRUE);
  2861.                     currentpos += 4;
  2862.  
  2863.                     label(" Name:");
  2864.                     uvalue = contents[which].name[currentpos++];
  2865.                     // the number of characters in the string
  2866.                     if (uvalue < MEDFIELD)
  2867.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), uvalue);
  2868.                     } else
  2869.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), MEDFIELD);
  2870.                     }
  2871.                     addreactionnode(&List2, tempstring1);
  2872.                     currentpos += uvalue;
  2873.                     if (uvalue % 2)
  2874.                     {   currentpos++; // skip pad byte, if appropriate
  2875.         }   }   }   }   }
  2876.         elif (!strcmp(contents[which].name, "AESD"))
  2877.         {   chunkdesc("Pertinent to autio recording devices", FALSE);
  2878.         } elif (!strcmp(contents[which].name, "COMT"))
  2879.         {   chunkdesc("Stores comments", TRUE);
  2880.  
  2881.         if (!iff.raw)
  2882.         {   label("Comments:");
  2883.             svalue = getsword(contents[which].DataPtr);
  2884.             snumcat(svalue, FALSE);
  2885.             if (svalue < 0)
  2886.             {   strcat(tempstring1, "!");
  2887.             }
  2888.             addreactionnode(&List2, tempstring1);
  2889.  
  2890.             // we could have a 'comments' variable, but we just reuse
  2891.             // the 'markers' variable.
  2892.             markers = svalue;
  2893.             if (markers > 0)
  2894.             {   currentpos = 2;
  2895.                 for (i = 1; i <= markers; i++)
  2896.                 {   strcpy(tempstring3, "Comment ");
  2897.                     stcl_d(tempstring2, i);
  2898.                     strcat(tempstring3, tempstring2);
  2899.                     strcat(tempstring3, ":");
  2900.                     label(tempstring3);
  2901.                     addreactionnode(&List2, tempstring1);
  2902.  
  2903.                     label(" Created on:");
  2904.                     uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  2905.                     DateTime.dat_Stamp.ds_Days   =   uvalue / 86400;             // days since 1/1/78
  2906.                     DateTime.dat_Stamp.ds_Minute =  (uvalue % 86400) / 60;       // minutes in day
  2907.                     DateTime.dat_Stamp.ds_Tick   = ((uvalue % 86400) % 60) * 50; // ticks in minute
  2908.                     DateTime.dat_Format          = FORMAT_DOS;
  2909.                     DateTime.dat_Flags           = DTF_SUBST;
  2910.                     DateTime.dat_StrDay          = weekdaystring;
  2911.                     DateTime.dat_StrDate         = datestring;
  2912.                     DateTime.dat_StrTime         = timestring;
  2913.                     if (!DateToStr(&DateTime))
  2914.                     {   rq("DateToStr() failed!");
  2915.                     }
  2916.                     strcat(tempstring1, timestring);
  2917.                     strcat(tempstring1, " ");
  2918.                     strcat(tempstring1, weekdaystring);
  2919.                     strcat(tempstring1, " ");
  2920.                     strcat(tempstring1, datestring);
  2921.                     addreactionnode(&List2, tempstring1);
  2922.                     currentpos += 4;
  2923.  
  2924.                     label(" Marker ID:");
  2925.                     svalue = getsword(&(contents[which].DataPtr[currentpos]));
  2926.                     snumcat(svalue, FALSE);
  2927.                     if (svalue < 1)
  2928.                     {    strcat(tempstring1, "!");
  2929.                     }
  2930.                     addreactionnode(&List2, tempstring1);
  2931.                     currentpos += 2;
  2932.  
  2933.                     label(" Comment:");
  2934.                     uvalue = getuword(&(contents[which].DataPtr[currentpos]));
  2935.                     // the number of characters in the string
  2936.                     currentpos += 2;
  2937.                     if (uvalue < MEDFIELD)
  2938.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), uvalue);
  2939.                     } else
  2940.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), MEDFIELD);
  2941.                     }
  2942.                     addreactionnode(&List2, tempstring1);
  2943.                     currentpos += uvalue;
  2944.                     if (uvalue % 2)
  2945.                     {   currentpos++; // skip pad byte, if appropriate
  2946.         }   }   }   }   }
  2947.         elif (!strcmp(contents[which].name, "COMM"))
  2948.         {   chunkdesc("Fundamental parameters for the sampled sound", TRUE);
  2949.  
  2950.         if (!iff.raw)
  2951.         {   label("Channels:");
  2952.             svalue = getsword(contents[which].DataPtr);
  2953.             snumcat(svalue, FALSE);
  2954.             if (svalue == 1)
  2955.             {   strcat(tempstring1, " (mono)");
  2956.             } elif (svalue == 2)
  2957.             {   strcat(tempstring1, " (stereo)");
  2958.             } elif (svalue > 2)
  2959.             {   strcat(tempstring1, " (surround)");
  2960.             }
  2961.             addreactionnode(&List2, tempstring1);
  2962.  
  2963.             label("Sample frames:");
  2964.             uvalue = getulong(&(contents[which].DataPtr[2]));
  2965.             unumcat(uvalue, TRUE);
  2966.  
  2967.             label("Sample quality:");
  2968.             svalue = getsword(&(contents[which].DataPtr[6]));
  2969.             snumcat(svalue, FALSE);
  2970.             strcat(tempstring1, "-bit");
  2971.             addreactionnode(&List2, tempstring1);
  2972.  
  2973.             /* Now there is an 80-bit (10-byte) IEEE 754 Apple-style
  2974.             (SANE) floating point number (not yet implemented):
  2975.                  79 Sign
  2976.               64:78 Exponent
  2977.                0:63 Mantissa */
  2978.  
  2979.             label("Playback rate:");
  2980.             strcat(tempstring1, "-");
  2981.             addreactionnode(&List2, tempstring1);
  2982.         }   }
  2983.         elif (!strcmp(contents[which].name, "APPL"))
  2984.         {   chunkdesc("Application-specific data", TRUE);
  2985.  
  2986.             if (!iff.raw)
  2987.             {   label("Application:");
  2988.                 strcat(tempstring1, contents[which].DataPtr);
  2989.                 if (!strcmp(tempstring1, "pdos"))
  2990.                 {   strcat(tempstring1, " (Apple II)");
  2991.                 }
  2992.                 addreactionnode(&List2, tempstring1);
  2993.         }   }
  2994.         elif (!strcmp(contents[which].name, "SSND"))
  2995.         {   chunkdesc("The actual sample frames", TRUE);
  2996.  
  2997.             if (!iff.raw)
  2998.             {   label("Offset:");
  2999.                 uvalue = getulong(contents[which].DataPtr);
  3000.                 unumcat(uvalue, TRUE);
  3001.  
  3002.                 label("Block size:");
  3003.                 uvalue = getulong(&(contents[which].DataPtr[4]));
  3004.                 unumcat(uvalue, TRUE);
  3005.         }   }
  3006.         elif (!strcmp(contents[which].name, "INST"))
  3007.         {   chunkdesc("Instrument chunk", TRUE);
  3008.  
  3009.         if (!iff.raw)
  3010.         {   label("Base note:");
  3011.             svalue = getsbyte(&(contents[which].DataPtr[0]));
  3012.             snumcat(svalue, FALSE);
  3013.             if (svalue < 0 || svalue > 127)
  3014.                 strcat(tempstring1, "!");
  3015.             addreactionnode(&List2, tempstring1);
  3016.  
  3017.             label("Detune:");
  3018.             svalue = getsbyte(&(contents[which].DataPtr[1]));
  3019.             snumcat(svalue, FALSE);
  3020.             if (svalue < -50 || svalue > 50)
  3021.                 strcat(tempstring1, "!");
  3022.             addreactionnode(&List2, tempstring1);
  3023.  
  3024.             label("Low note:");
  3025.             svalue = getsbyte(&(contents[which].DataPtr[2]));
  3026.             snumcat(svalue, FALSE);
  3027.             if (svalue < 0 || svalue > 127) // actually these couldn't be >127
  3028.                 strcat(tempstring1, "!");
  3029.             addreactionnode(&List2, tempstring1);
  3030.  
  3031.             label("High note:");
  3032.             svalue = getsbyte(&(contents[which].DataPtr[3]));
  3033.             snumcat(svalue, FALSE);
  3034.             if (svalue < 0 || svalue > 127)
  3035.                 strcat(tempstring1, "!");
  3036.             addreactionnode(&List2, tempstring1);
  3037.  
  3038.             label("Low velocity:");
  3039.             svalue = getsbyte(&(contents[which].DataPtr[4]));
  3040.             snumcat(svalue, FALSE);
  3041.             if (svalue < 1 || svalue > 127)
  3042.                 strcat(tempstring1, "!");
  3043.             addreactionnode(&List2, tempstring1);
  3044.  
  3045.             label("High velocity:");
  3046.             svalue = getsbyte(&(contents[which].DataPtr[5]));
  3047.             snumcat(svalue, FALSE);
  3048.             if (svalue < 1 || svalue > 127)
  3049.                 strcat(tempstring1, "!");
  3050.             addreactionnode(&List2, tempstring1);
  3051.  
  3052.             label("Gain:");
  3053.             svalue = getsword(&(contents[which].DataPtr[6]));
  3054.             snumcat(svalue, TRUE);
  3055.  
  3056.             label("Sustain loop:");
  3057.             svalue = getsword(&(contents[which].DataPtr[8]));
  3058.             interpret(47, (ULONG) svalue);
  3059.  
  3060.             label(" Begin loop:");
  3061.             svalue = getsword(&(contents[which].DataPtr[10]));
  3062.             snumcat(svalue, TRUE);
  3063.  
  3064.             label(" End loop:");
  3065.             svalue = getsword(&(contents[which].DataPtr[12]));
  3066.             snumcat(svalue, TRUE);
  3067.  
  3068.             label("Release loop:");
  3069.             svalue = getsword(&(contents[which].DataPtr[14]));
  3070.             interpret(47, (ULONG) svalue);
  3071.  
  3072.             label(" Begin loop:");
  3073.             svalue = getsword(&(contents[which].DataPtr[16]));
  3074.             snumcat(svalue, TRUE);
  3075.  
  3076.             label(" End loop:");
  3077.             svalue = getsword(&(contents[which].DataPtr[18]));
  3078.             snumcat(svalue, TRUE);
  3079.     }   }   }
  3080.     elif (!strcmp(queryform, "CTLG"))
  3081.     {   if (!strcmp(contents[which].name, "LANG"))
  3082.         {   chunkdesc("Language", TRUE);
  3083.  
  3084.             if (!iff.raw)
  3085.             {   label("Language:");
  3086.                 strcat(tempstring1, contents[which].DataPtr);
  3087.                 addreactionnode(&List2, tempstring1);
  3088.         }   }
  3089.         // CSET chunk (32 bytes), STRS chunk?
  3090.     } elif (!strcmp(queryform, "8SVX"))
  3091.     {   if (!strcmp(contents[which].name, "ATAK"))
  3092.         {   chunkdesc("Gives attack amplitude contour (envelope)", FALSE);
  3093.         } elif (!strcmp(contents[which].name, "RLSE"))
  3094.         {   chunkdesc("Gives release amplitude contour (envelope)", FALSE);
  3095.         } elif (!strcmp(contents[which].name, "BODY"))
  3096.         {   chunkdesc("Sound data chunk", FALSE);
  3097.         } elif (!strcmp(contents[which].name, "FADE"))
  3098.         {   chunkdesc("Fade away to silence", TRUE);
  3099.  
  3100.             if (!iff.raw)
  3101.             {   label("Fade start:");
  3102.                 uvalue = getulong(contents[which].DataPtr);
  3103.                 unumcat(uvalue, TRUE);
  3104.         }   }
  3105.         elif (!strcmp(contents[which].name, "SEQN"))
  3106.         {   chunkdesc("Multiple loop sequencing", TRUE);
  3107.  
  3108.         if (!iff.raw)
  3109.         {
  3110.             currentpos = 0;
  3111.             while (currentpos < contents[which].bytes)
  3112.             {   label("Loop start:");
  3113.                 uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  3114.                 unumcat(uvalue, FALSE);
  3115.                 if (uvalue % 4)
  3116.                 {   strcat(tempstring1, "!");
  3117.                 }
  3118.                 addreactionnode(&List2, tempstring1);
  3119.                 currentpos += 4;
  3120.  
  3121.                 label("Loop end:");
  3122.                 uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  3123.                 unumcat(uvalue, FALSE);
  3124.                 if (uvalue % 4)
  3125.                 {   strcat(tempstring1, "!");
  3126.                 }
  3127.                 addreactionnode(&List2, tempstring1);
  3128.                 currentpos += 4;
  3129.         }   }   }
  3130.         elif (!strcmp(contents[which].name, "CHAN"))
  3131.         {   chunkdesc("Specified channel, or combination of channels", TRUE);
  3132.  
  3133.             if (!iff.raw)
  3134.             {   label("Channel:");
  3135.                 svalue = getslong(contents[which].DataPtr);
  3136.                 if (svalue == 2)
  3137.                 {   strcat(tempstring1, "Left");
  3138.                 } elif (svalue == 4)
  3139.                 {   strcat(tempstring1, "Right");
  3140.                 } elif (svalue == 6)
  3141.                 {   strcat(tempstring1, "Stereo (both)");
  3142.                 } else strcat(tempstring1, "?");
  3143.                 addreactionnode(&List2, tempstring1);
  3144.         }   }
  3145.         elif (!strcmp(contents[which].name, "PAN "))
  3146.         {   chunkdesc("Stereo sound using a single array of data", TRUE);
  3147.  
  3148.             if (!iff.raw)
  3149.             {   label("Sound position:");
  3150.                 svalue = getslong(contents[which].DataPtr);
  3151.                 snumcat(svalue, FALSE);
  3152.                 strcat(tempstring1, "/65536 ");
  3153.                 if (svalue < 32768)
  3154.                 {    strcat(tempstring1, "(left)");
  3155.                 } elif (svalue > 32678)
  3156.                 {    strcat(tempstring1, "(right)");
  3157.                 } else
  3158.                 {    // assert(svalue == 32678);
  3159.                      strcat(tempstring1, "(centre)");
  3160.                 }
  3161.                 addreactionnode(&List2, tempstring1);
  3162.         }   }
  3163.         elif (!strcmp(contents[which].name, "VHDR"))
  3164.         {   chunkdesc("Playback parameters for the sampled waveforms", TRUE);
  3165.  
  3166.             if (!iff.raw)
  3167.             {   label("1-shot samples:");
  3168.                 uvalue = getulong(contents[which].DataPtr);
  3169.                 unumcat(uvalue, TRUE);
  3170.  
  3171.                 label("Repeat samples:");
  3172.                 uvalue = getulong(&(contents[which].DataPtr[4]));
  3173.                 unumcat(uvalue, TRUE);
  3174.  
  3175.                 label("Samples per cycle:");
  3176.                 uvalue = getulong(&(contents[which].DataPtr[8]));
  3177.                 unumcat(uvalue, TRUE);
  3178.  
  3179.                 label("Sampling rate:");
  3180.                 uvalue = getuword(&(contents[which].DataPtr[12]));
  3181.                 unumcat(uvalue, TRUE);
  3182.  
  3183.                 label("Octaves:");
  3184.                 snumcat((SLONG) contents[which].DataPtr[14], TRUE); // UBYTE
  3185.  
  3186.                 label("Compression:"); // UBYTE
  3187.                 interpret(48, (ULONG) contents[which].DataPtr[15]);
  3188.  
  3189.                 label("Volume:");
  3190.                 svalue = getslong(&(contents[which].DataPtr[16]));
  3191.                 svalue /= 1024; // LONG (Fixed)
  3192.                 snumcat(svalue, FALSE);
  3193.                 strcat(tempstring1, "/64");
  3194.                 addreactionnode(&List2, tempstring1);
  3195.     }   }   }
  3196.     elif (!strcmp(queryform, "ILBM") || !strcmp(queryform, "ABCM") || !strcmp(queryform, "ANIM"))
  3197.     {   if (!strcmp(contents[which].name, "CAMG"))
  3198.         {   chunkdesc("Amiga display mode of a picture", TRUE);
  3199.  
  3200.             if (!iff.raw)
  3201.             {   label("ModeID:");
  3202.                 strcat(tempstring1, "$");
  3203.                 hexalize(contents[which].DataPtr[0]);
  3204.                 hexalize(contents[which].DataPtr[1]);
  3205.                 hexalize(contents[which].DataPtr[2]);
  3206.                 hexalize(contents[which].DataPtr[3]);
  3207.                 addreactionnode(&List2, tempstring1);
  3208.         }   }
  3209.         elif (!strcmp(queryform, "ANIM") && !strcmp(contents[which].name, "ANHD"))
  3210.         {   chunkdesc("Animation header", TRUE);
  3211.  
  3212.         if (!iff.raw)
  3213.         {   label("Compression method:");
  3214.             if (contents[which].DataPtr[0] == 74) // not a typo
  3215.             {   strcat(tempstring1, "74 (Eric Graham)");
  3216.             } else
  3217.             {   interpret(49, (ULONG) contents[which].DataPtr[0]);
  3218.             }
  3219.  
  3220.             label("Mask:");
  3221.             strcat(tempstring1, "%");
  3222.             binarize(contents[which].DataPtr[1]);
  3223.             addreactionnode(&List2, tempstring1);
  3224.  
  3225.             label("Entire width:");
  3226.             uvalue = getuword(&contents[which].DataPtr[2]); // UWORD
  3227.             unumcat(uvalue, FALSE);
  3228.             strcat(tempstring1, " pixels");
  3229.             addreactionnode(&List2, tempstring1);
  3230.  
  3231.             label("Entire height:");
  3232.             uvalue = getuword(&contents[which].DataPtr[4]); // UWORD
  3233.             unumcat(uvalue, FALSE);
  3234.             strcat(tempstring1, " pixels");
  3235.             addreactionnode(&List2, tempstring1);
  3236.  
  3237.             label("Width:");
  3238.             svalue = getsword(&contents[which].DataPtr[6]); // WORD
  3239.             snumcat(svalue, FALSE);
  3240.             strcat(tempstring1, " pixels");
  3241.             addreactionnode(&List2, tempstring1);
  3242.  
  3243.             label("Height:");
  3244.             svalue = getsword(&contents[which].DataPtr[8]); // WORD
  3245.             snumcat(svalue, FALSE);
  3246.             strcat(tempstring1, " pixels");
  3247.             addreactionnode(&List2, tempstring1);
  3248.  
  3249.             label("Absolute time:");
  3250.             uvalue = getulong(&contents[which].DataPtr[10]); // ULONG
  3251.             unumcat(uvalue, FALSE);
  3252.             strcat(tempstring1, "/60 of a second");
  3253.             addreactionnode(&List2, tempstring1);
  3254.  
  3255.             label("Relative time:");
  3256.             uvalue = getulong(&contents[which].DataPtr[14]); // ULONG
  3257.             unumcat(uvalue, FALSE);
  3258.             strcat(tempstring1, "/60 of a second");
  3259.             addreactionnode(&List2, tempstring1);
  3260.  
  3261.             label("Interleave:");
  3262.             if (contents[which].DataPtr[18] == 0)
  3263.             {   strcat(tempstring1, "0 (2 frames back)");
  3264.             } else
  3265.             {   stcl_d(tempstring2, contents[which].DataPtr[18]);
  3266.                 strcat(tempstring1, tempstring2);
  3267.                 strcat(tempstring1, " frames back");
  3268.             }
  3269.             addreactionnode(&List2, tempstring1);
  3270.  
  3271.             // now a pad byte (19)
  3272.  
  3273.             label("Flags:");
  3274.             uvalue = getulong(&contents[which].DataPtr[20]); // ULONG
  3275.  
  3276.             label(" Data length:");
  3277.             if (uvalue & 1)
  3278.             {   strcat(tempstring1, "Long");
  3279.             } else
  3280.             {   strcat(tempstring1, "Short");
  3281.             }
  3282.             addreactionnode(&List2, tempstring1);
  3283.  
  3284.             label(" Set/XOR:");
  3285.             if (uvalue & 2)
  3286.             {   strcat(tempstring1, "Set");
  3287.             } else
  3288.             {   strcat(tempstring1, "XOR");
  3289.             }
  3290.             addreactionnode(&List2, tempstring1);
  3291.  
  3292.             label(" Info:");
  3293.             if (uvalue & 4)
  3294.             {   strcat(tempstring1, "One info list for all planes");
  3295.             } else
  3296.             {   strcat(tempstring1, "Separate info for each plane");
  3297.             }
  3298.             addreactionnode(&List2, tempstring1);
  3299.  
  3300.             label(" Run length encoded?");
  3301.             dobool((UBYTE) (uvalue & 8));
  3302.  
  3303.             label(" Encoding:");
  3304.             if (uvalue & 16)
  3305.             {   strcat(tempstring1, "Vertical");
  3306.             } else
  3307.             {   strcat(tempstring1, "Horizontal");
  3308.             }
  3309.             addreactionnode(&List2, tempstring1);
  3310.  
  3311.             label(" Info offsets:");
  3312.             if (uvalue & 32)
  3313.             {   strcat(tempstring1, "Short");
  3314.             } else
  3315.             {   strcat(tempstring1, "Long");
  3316.             }
  3317.             addreactionnode(&List2, tempstring1);
  3318.  
  3319.             // now 16 reserved bytes
  3320.         }   }
  3321.         elif (!strcmp(queryform, "ANIM") && !strcmp(contents[which].name, "DLTA"))
  3322.         {   chunkdesc("Delta compression data", FALSE);
  3323.         } elif (!strcmp(contents[which].name, "DPI "))
  3324.         {   chunkdesc("Dots per inch", TRUE);
  3325.  
  3326.             if (!iff.raw)
  3327.             {   label("Dots per inch:");
  3328.                 // There are 20 characters in the first column.
  3329.                 uvalue = getuword(contents[which].DataPtr);
  3330.                 unumcat(uvalue, FALSE);
  3331.                 strcat(tempstring1, "x");
  3332.                 uvalue = getuword(&(contents[which].DataPtr[2]));
  3333.                 unumcat(uvalue, TRUE);
  3334.         }   }
  3335.         elif (!strcmp(contents[which].name, "CMAP"))
  3336.         {   chunkdesc("Colour map data", FALSE);
  3337.         } elif (!strcmp(contents[which].name, "BODY"))
  3338.         {   chunkdesc("Image data chunk", FALSE);
  3339.         } elif (!strcmp(contents[which].name, "EPSF"))
  3340.         {   chunkdesc("Encapsulated PostScript representation of image", TRUE);
  3341.  
  3342.         if (!iff.raw)
  3343.         {
  3344.             label("Left X:");
  3345.             svalue = getsword(contents[which].DataPtr);
  3346.             snumcat(svalue, TRUE);
  3347.  
  3348.             label("Top Y:");
  3349.             svalue = getsword(&(contents[which].DataPtr[2]));
  3350.             snumcat(svalue, TRUE);
  3351.  
  3352.             label("Right X:");
  3353.             svalue = getsword(&(contents[which].DataPtr[4]));
  3354.             snumcat(svalue, TRUE);
  3355.  
  3356.             label("Bottom Y:");
  3357.             svalue = getsword(&(contents[which].DataPtr[6]));
  3358.             snumcat(svalue, TRUE);
  3359.         }   }
  3360.         elif (!strcmp(contents[which].name, "DEST"))
  3361.         {   chunkdesc("Scatter bitplanes into a deeper destination image", TRUE);
  3362.  
  3363.         if (!iff.raw)
  3364.         {
  3365.             label("Source bitplanes:");
  3366.             snumcat((SLONG) contents[which].DataPtr[0], TRUE);
  3367.  
  3368.             // next (1) is a pad byte.
  3369.  
  3370.             label("PlanePick:");
  3371.             strcat(tempstring1, "%"); // UWORD
  3372.             binarize(contents[which].DataPtr[2]);
  3373.             binarize(contents[which].DataPtr[3]);
  3374.             addreactionnode(&List2, tempstring1);
  3375.  
  3376.             label("PlaneOnOff:");
  3377.             strcat(tempstring1, "%"); // UWORD
  3378.             binarize(contents[which].DataPtr[4]);
  3379.             binarize(contents[which].DataPtr[5]);
  3380.             addreactionnode(&List2, tempstring1);
  3381.  
  3382.             label("PlaneMask:");
  3383.             strcat(tempstring1, "%"); // UWORD
  3384.             binarize(contents[which].DataPtr[6]);
  3385.             binarize(contents[which].DataPtr[7]);
  3386.             addreactionnode(&List2, tempstring1);
  3387.         }   }
  3388.         elif (!strcmp(contents[which].name, "GRAB"))
  3389.         {   chunkdesc("Locates a hotspot, when used as a pointer or brush", TRUE);
  3390.  
  3391.             if (!iff.raw)
  3392.             {   label("Hotspot:");
  3393.                 svalue = getsword(contents[which].DataPtr);
  3394.                 snumcat(svalue, FALSE);
  3395.                 strcat(tempstring1, ",");
  3396.                 svalue = getsword(&(contents[which].DataPtr[2]));
  3397.                 snumcat(svalue, TRUE);
  3398.         }   }
  3399.         elif (!strcmp(contents[which].name, "SPRT"))
  3400.         {   chunkdesc("This image is intended as a sprite", TRUE);
  3401.  
  3402.             if (!iff.raw)
  3403.             {   label("Precedence:");
  3404.                 uvalue = getuword(contents[which].DataPtr);
  3405.                 unumcat(uvalue, TRUE);
  3406.         }   }
  3407.         elif (!strcmp(contents[which].name, "BMHD"))
  3408.         {   /* UWORD w, h;               0-1, 2-3
  3409.             WORD  x, y;                  4-5, 6-7
  3410.             UBYTE nPlanes;               8
  3411.             UBYTE Masking;               9
  3412.             UBYTE Compression;           10
  3413.             UBYTE pad;                   11
  3414.             UWORD transparentColour;     12-13
  3415.             UBYTE xAspect, yAspect;      14, 15
  3416.             WORD  pageWidth, pageHeight; 16-17, 18-19 */
  3417.  
  3418.             chunkdesc("Data necessary to understand the BODY chunk", TRUE);
  3419.  
  3420.             if (!iff.raw)
  3421.             {
  3422.             label("Image size:");
  3423.             uvalue = getuword(contents[which].DataPtr); // UWORD
  3424.             unumcat(uvalue, FALSE);
  3425.             strcat(tempstring1, "x");
  3426.             uvalue = getuword(&(contents[which].DataPtr[2])); // UWORD
  3427.             unumcat(uvalue, TRUE);
  3428.  
  3429.             label("Position:");
  3430.             svalue = getsword(&(contents[which].DataPtr[4])); // WORD
  3431.             snumcat(svalue, FALSE);
  3432.             strcat(tempstring1, ",");
  3433.             svalue = getsword(&(contents[which].DataPtr[6])); // WORD
  3434.             snumcat(svalue, TRUE);
  3435.  
  3436.             label("Bitplanes:");
  3437.             snumcat((SLONG) contents[which].DataPtr[8], TRUE);
  3438.             // tell number of colours to user?
  3439.  
  3440.             label("Masking:");
  3441.             interpret(45, (ULONG) contents[which].DataPtr[9]);
  3442.  
  3443.             label("Compression:");
  3444.             interpret(46, (ULONG) contents[which].DataPtr[10]);
  3445.  
  3446.             // Next (11) is a pad byte.
  3447.  
  3448.             label("Transparent colour:");
  3449.             if (contents[which].DataPtr[9] != 2
  3450.              && contents[which].DataPtr[9] != 3)
  3451.             {   strcat(tempstring1, "n/a");
  3452.                 addreactionnode(&List2, tempstring1);
  3453.             } else
  3454.             {   uvalue = getuword(&(contents[which].DataPtr[12]));
  3455.                 unumcat(uvalue, TRUE);
  3456.             }
  3457.  
  3458.             label("Aspect ratio:");
  3459.             snumcat((SLONG) contents[which].DataPtr[14], FALSE);
  3460.             strcat(tempstring1, ":");
  3461.             snumcat((SLONG) contents[which].DataPtr[15], TRUE);
  3462.  
  3463.             label("Page size:");
  3464.             svalue = getsword(&(contents[which].DataPtr[16])); // WORD
  3465.             snumcat(svalue, FALSE);
  3466.             strcat(tempstring1, "x");
  3467.             svalue = getsword(&(contents[which].DataPtr[18])); // WORD
  3468.             snumcat(svalue, TRUE);
  3469.     }   }   }
  3470.     elif (!strcmp(queryform, "RSND"))
  3471.     {   if (!strcmp(contents[which].name, "RSHD"))
  3472.         {   chunkdesc("Sound header", TRUE);
  3473.  
  3474.             if (!iff.raw)
  3475.             {   label("Length:");
  3476.                 uvalue = getulong(contents[which].DataPtr); // ULONG
  3477.                 unumcat(uvalue, TRUE);
  3478.  
  3479.                 label("Frequency:");
  3480.                 uvalue = getulong(&contents[which].DataPtr[4]); // ULONG
  3481.                 unumcat(uvalue, TRUE);
  3482.  
  3483.                 label("Bits per sample:");
  3484.                 uvalue = getulong(&contents[which].DataPtr[8]); // ULONG
  3485.                 unumcat(uvalue, TRUE);
  3486.  
  3487.                 label("Number of channels:");
  3488.                 uvalue = getulong(&contents[which].DataPtr[12]); // ULONG
  3489.                 unumcat(uvalue, TRUE);
  3490.         }   }
  3491.         elif (!strcmp(contents[which].name, "RBOD"))
  3492.         {   chunkdesc("Sound body", FALSE);
  3493.     }   }
  3494.  
  3495.     if (!known || iff.raw)
  3496.     {   for (i = 0; i < contents[which].bytes; i += BYTESPERLINE)
  3497.         {   strcpy(tempstring1, "$");
  3498.  
  3499.             hexalize(i / 16777216); // do 1st byte
  3500.             j = i % 16777216;       // remove 1st byte
  3501.             hexalize(j / 65536);    // do 2nd byte
  3502.             j %= 65536;             // remove 2nd byte
  3503.             hexalize(j / 256);      // do 3rd byte
  3504.             hexalize(j % 256);      // do 4th byte
  3505.  
  3506.             strcat(tempstring1, ": ");
  3507.             for (j = 0; j < BYTESPERLINE; j++)
  3508.             {   if (contents[which].bytes > i + j)
  3509.                 {   hexalize(contents[which].DataPtr[i + j]);
  3510.                 } else
  3511.                 {   strcat(tempstring1, "##");
  3512.                 }
  3513.                 if (j % 2)
  3514.                 {   strcat(tempstring1, " ");
  3515.             }   }
  3516.             for (j = 0; j < BYTESPERLINE; j++)
  3517.             {   if (contents[which].bytes > i + j)
  3518.                 {   if (contents[which].DataPtr[i + j] < ' ') // if an unprintable character
  3519.                     {   strcat(tempstring1, ".");
  3520.                     } else
  3521.                     {   length = strlen(tempstring1);
  3522.                         tempstring1[length] = contents[which].DataPtr[i + j];
  3523.                         tempstring1[length + 1] = 0;
  3524.                 }   }
  3525.                 else
  3526.                 {   strcat(tempstring1, "#");
  3527.             }   }
  3528.             addreactionnode(&List2, tempstring1);
  3529.     }   }
  3530.     if (!known)
  3531.     {   chunkdesc("?", FALSE);
  3532.     }
  3533.  
  3534.     SetGadgetAttrs
  3535.     (   iff_gadgets[GID_6_LB2],
  3536.         MainWindowPtr, NULL,
  3537.         LISTBROWSER_Labels, &List2,
  3538.         TAG_END
  3539.     );
  3540. }
  3541.  
  3542. MODULE void chunkdesc(STRPTR desc, ABOOL isknown)
  3543. {   SetGadgetAttrs
  3544.     (   iff_gadgets[GID_6_ST4],
  3545.         MainWindowPtr, NULL,
  3546.         STRINGA_TextVal, desc,
  3547.         TAG_END
  3548.     );
  3549.     known = isknown;
  3550. }
  3551.  
  3552. MODULE void binarize(UBYTE data)
  3553. {   SLONG i; // must be signed
  3554.  
  3555.     for (i = 7; i >= 0; i--)
  3556.     {   if (data & (1 << i))
  3557.         {   strcat(tempstring1, "1");
  3558.         } else
  3559.         {   strcat(tempstring1, "0");
  3560. }   }   }
  3561.  
  3562. MODULE void hexalize(UBYTE data)
  3563. {   // Converts an unsigned byte into a hexadecimal string
  3564.  
  3565.     // do the high byte
  3566.     if (data / 16 >= 10)
  3567.     {   tempstring2[0] = (data / 16) - 10 + 'A'; // must be done in this order to prevent overflow during calculation of the value
  3568.     } else
  3569.     {   tempstring2[0] = (data / 16) + '0';
  3570.     }
  3571.  
  3572.     // now the low byte
  3573.     if (data % 16 >= 10)
  3574.     {   tempstring2[1] = (data % 16) - 10 + 'A';
  3575.     } else
  3576.     {   tempstring2[1] = (data % 16) + '0';
  3577.     }
  3578.     tempstring2[2] = 0;
  3579.     strcat(tempstring1, tempstring2);
  3580. }
  3581.  
  3582. MODULE ULONG getulong(UBYTE* start)
  3583. {   return (ULONG) ((16777216 * *(start    ))
  3584.                   + (   65536 * *(start + 1))
  3585.                   + (     256 * *(start + 2))
  3586.                   +             *(start + 3));
  3587. }
  3588. MODULE SLONG getslong(UBYTE* start)
  3589. {   return (SLONG) ((16777216 * *(start    ))
  3590.                   + (   65536 * *(start + 1))
  3591.                   + (     256 * *(start + 2))
  3592.                   +             *(start + 3));
  3593. }
  3594. MODULE ULONG getuword(UBYTE* start)
  3595. {   return (ULONG) ((     256 * *(start    ))
  3596.                   +             *(start + 1));
  3597. }
  3598. MODULE SLONG getsword(UBYTE* start)
  3599. {   return (SLONG) ((     256 * *(start    ))
  3600.                   +             *(start + 1));
  3601. }
  3602. MODULE SLONG getsbyte(UBYTE* start)
  3603. {   return (SBYTE) (*start);
  3604. }
  3605.  
  3606. MODULE void writeiffgadgets(void)
  3607. {   // update the gadgets according to variables
  3608.  
  3609.     SetGadgetAttrs
  3610.     (   iff_gadgets[GID_6_CB2], MainWindowPtr, NULL,
  3611.         GA_Selected, iff.obsolete,
  3612.     TAG_END);
  3613.     RefreshGadgets((struct Gadget *) iff_gadgets[GID_6_CB2], MainWindowPtr, NULL);
  3614.     SetGadgetAttrs
  3615.     (   iff_gadgets[GID_6_CB3], MainWindowPtr, NULL,
  3616.         GA_Selected, iff.private,
  3617.     TAG_END);
  3618.     RefreshGadgets((struct Gadget *) iff_gadgets[GID_6_CB3], MainWindowPtr, NULL);
  3619.     SetGadgetAttrs
  3620.     (   iff_gadgets[GID_6_CB4], MainWindowPtr, NULL,
  3621.         GA_Selected, iff.proposal,
  3622.     TAG_END);
  3623.     RefreshGadgets((struct Gadget *) iff_gadgets[GID_6_CB4], MainWindowPtr, NULL);
  3624.     SetGadgetAttrs
  3625.     (   iff_gadgets[GID_6_CB5], MainWindowPtr, NULL,
  3626.         GA_Selected, iff.reserved,
  3627.     TAG_END);
  3628.     RefreshGadgets((struct Gadget *) iff_gadgets[GID_6_CB5], MainWindowPtr, NULL);
  3629.     SetGadgetAttrs
  3630.     (   iff_gadgets[GID_6_CB6], MainWindowPtr, NULL,
  3631.         GA_Selected, iff.standard,
  3632.     TAG_END);
  3633.     RefreshGadgets((struct Gadget *) iff_gadgets[GID_6_CB6], MainWindowPtr, NULL);
  3634.     SetGadgetAttrs
  3635.     (   iff_gadgets[GID_6_CB7], MainWindowPtr, NULL,
  3636.         GA_Selected, iff.unregistered,
  3637.     TAG_END);
  3638.     RefreshGadgets((struct Gadget *) iff_gadgets[GID_6_CB7], MainWindowPtr, NULL);
  3639.     SetGadgetAttrs
  3640.     (   iff_gadgets[GID_6_CB8], MainWindowPtr, NULL,
  3641.         GA_Selected, iff.rkm,
  3642.     TAG_END);
  3643.     RefreshGadgets((struct Gadget *) iff_gadgets[GID_6_CB8], MainWindowPtr, NULL);
  3644.     SetGadgetAttrs
  3645.     (   iff_gadgets[GID_6_CB9], MainWindowPtr, NULL,
  3646.         GA_Selected, iff.cd,
  3647.     TAG_END);
  3648.     RefreshGadgets((struct Gadget *) iff_gadgets[GID_6_CB9], MainWindowPtr, NULL);
  3649.     SetGadgetAttrs
  3650.     (   iff_gadgets[GID_6_ST1],
  3651.         MainWindowPtr, NULL,
  3652.         STRINGA_TextVal, queryform,
  3653.         TAG_END
  3654.     );
  3655.     chunkdesc("-", FALSE);
  3656. }
  3657.  
  3658. MODULE void dotextattr(UBYTE* offset)
  3659. {   ULONG uvalue;
  3660.  
  3661.     // handles TextAttr structure (8 bytes)
  3662.     // name pointer is ignored
  3663.  
  3664.     label(" Height:");
  3665.     uvalue = getuword(offset + 4);
  3666.     unumcat(uvalue, TRUE);
  3667.  
  3668.     addreactionnode(&List2, " Style:");
  3669.  
  3670.     label("  Underlined?");
  3671.     dobool((*(offset + 6)) & 1); // FSF_UNDERLINED
  3672.  
  3673.     label("  Bold?");
  3674.     dobool((*(offset + 6)) & 2); // FSF_BOLD
  3675.  
  3676.     label("  Italic?");
  3677.     dobool((*(offset + 6)) & 4); // FSF_ITALIC
  3678.  
  3679.     label("  Extended?");
  3680.     dobool((*(offset + 6)) & 8); // FSF_EXTENDED
  3681.  
  3682.     label("  Colour font?");
  3683.     dobool((*(offset + 6)) & 64); // FSF_COLORFONT
  3684.  
  3685.     label("  Tagged?");
  3686.     dobool((*(offset + 6)) & 128); // FSF_TAGGED
  3687.  
  3688.     addreactionnode(&List2, " Flags:");
  3689.  
  3690.     label("  ROM font?");
  3691.     dobool((*(offset + 7)) & 1); // FPF_ROMFONT
  3692.  
  3693.     label("  Disk font?");
  3694.     dobool((*(offset + 7)) & 2); // FPF_DISKFONT
  3695.  
  3696.     label("  Reversed?");
  3697.     dobool((*(offset + 7)) & 4); // FPF_REVPATH
  3698.  
  3699.     label("  HiRes non-interlaced?");
  3700.     dobool((*(offset + 7)) & 8); // FPF_TALLDOT
  3701.  
  3702.     label("  LoRes interlaced?");
  3703.     dobool((*(offset + 7)) & 16); // FPF_WIDEDOT
  3704.  
  3705.     label("  Proportional?");
  3706.     dobool((*(offset + 7)) & 32); // FPF_PROPORTIONAL
  3707.  
  3708.     label("  Designed?");
  3709.     dobool((*(offset + 7)) & 64); // FPF_DESIGNED
  3710.  
  3711.     label("  Removed?");
  3712.     // this one has a ! after its `Yes', since it should never be TRUE.
  3713.     if (*(offset + 7) & 128) // FPF_REMOVED
  3714.     {   strcat(tempstring1, "Yes!");
  3715.     } else
  3716.     {   strcat(tempstring1, "No");
  3717.     }
  3718.     addreactionnode(&List2, tempstring1);
  3719. }
  3720.  
  3721. MODULE void docountry(UBYTE* offset)
  3722. {   ULONG uvalue;
  3723.  
  3724.     // handles CountryPrefs structure (8 bytes)
  3725.  
  3726.     // 16 reserved bytes at start
  3727.  
  3728.     label("Country code:");
  3729.     uvalue = getulong(offset + 16); // ULONG
  3730.     unumcat(uvalue, TRUE);
  3731.  
  3732.     label("Telephone code:");
  3733.     uvalue = getulong(offset + 20); // ULONG
  3734.     unumcat(uvalue, TRUE);
  3735.  
  3736.     label("Measuring system:");
  3737.     interpret(50, (ULONG) *(offset + 24));
  3738.  
  3739.     label("Long date/time format:");
  3740.     strcat(tempstring1, offset + 25); // 80 chars
  3741.     addreactionnode(&List2, tempstring1);
  3742.  
  3743.     label("Long date format:");
  3744.     strcat(tempstring1, offset + 105); // 40 chars
  3745.     addreactionnode(&List2, tempstring1);
  3746.  
  3747.     label("Long time format:");
  3748.     strcat(tempstring1, offset + 145); // 40 chars
  3749.     addreactionnode(&List2, tempstring1);
  3750.  
  3751.     label("Short date/time format:");
  3752.     strcat(tempstring1, offset + 185); // 80 chars
  3753.     addreactionnode(&List2, tempstring1);
  3754.  
  3755.     label("Short date format:");
  3756.     strcat(tempstring1, offset + 265); // 40 chars
  3757.     addreactionnode(&List2, tempstring1);
  3758.  
  3759.     label("Short time format:");
  3760.     strcat(tempstring1, offset + 305); // 40 chars
  3761.     addreactionnode(&List2, tempstring1);
  3762.  
  3763.     addreactionnode(&List2, "Numeric values:");
  3764.  
  3765.     label(" Decimal point:");
  3766.     strcat(tempstring1, offset + 345); // 10 chars
  3767.     addreactionnode(&List2, tempstring1);
  3768.  
  3769.     label(" Intgr group separator:");
  3770.     strcat(tempstring1, offset + 355); // 10 chars
  3771.     addreactionnode(&List2, tempstring1);
  3772.  
  3773.     label(" Frac. group separator:");
  3774.     strcat(tempstring1, offset + 365); // 10 chars
  3775.     addreactionnode(&List2, tempstring1);
  3776.  
  3777.     /* Integer group size (10 chars) and
  3778.        Fractional group size (10 chars): not strings (currently skipped */
  3779.  
  3780.     addreactionnode(&List2, "General monetary values:");
  3781.  
  3782.     label(" Decimal point:");
  3783.     strcat(tempstring1, offset + 395); // 10 chars
  3784.     addreactionnode(&List2, tempstring1);
  3785.  
  3786.     label(" Intgr group separator:");
  3787.     strcat(tempstring1, offset + 405); // 10 chars
  3788.     addreactionnode(&List2, tempstring1);
  3789.  
  3790.     label(" Frac. group separator:");
  3791.     strcat(tempstring1, offset + 415); // 10 chars
  3792.     addreactionnode(&List2, tempstring1);
  3793.  
  3794.     /* Integer group size (10 chars) and
  3795.        Fractional group size (10 chars): not strings (currently skipped) */
  3796.  
  3797.     addreactionnode(&List2, " Digits after decimal point:");
  3798.  
  3799.     label("  Intranational:");
  3800.     snumcat((SLONG) ((UBYTE) *(offset + 445)), TRUE);
  3801.  
  3802.     label("  International:");
  3803.     snumcat((SLONG) ((UBYTE) *(offset + 446)), TRUE);
  3804.  
  3805.     addreactionnode(&List2, "Currency symbols:");
  3806.  
  3807.     label(" Large amounts symbol:");
  3808.     strcat(tempstring1, offset + 447); // 10 chars
  3809.     addreactionnode(&List2, tempstring1);
  3810.  
  3811.     label(" Small amounts symbol:");
  3812.     strcat(tempstring1, offset + 457); // 10 chars
  3813.     addreactionnode(&List2, tempstring1);
  3814.  
  3815.     label(" ISO 4217 code:");
  3816.     strcat(tempstring1, offset + 467); // 10 chars
  3817.     addreactionnode(&List2, tempstring1);
  3818.  
  3819.     addreactionnode(&List2, "Positive monetary values:");
  3820.  
  3821.     label(" Positive sign:");
  3822.     strcat(tempstring1, offset + 477); // 10 chars
  3823.     addreactionnode(&List2, tempstring1);
  3824.  
  3825.     label(" Space next to sign?");
  3826.     interpret(51, (ULONG) *(offset + 487));
  3827.  
  3828.     label(" Positive sign pos.:");
  3829.     interpret(52, (ULONG) *(offset + 488));
  3830.  
  3831.     label(" Currency symbol pos.:");
  3832.     interpret(53, (ULONG) *(offset + 489));
  3833.  
  3834.     addreactionnode(&List2, "Negative monetary values:");
  3835.  
  3836.     label(" Negative sign:");
  3837.     strcat(tempstring1, offset + 500); // 10 chars
  3838.     addreactionnode(&List2, tempstring1);
  3839.  
  3840.     label(" Space next to sign?");
  3841.     interpret(51, (ULONG) *(offset + 500));
  3842.  
  3843.     label(" Negative sign pos.:");
  3844.     interpret(52, (ULONG) *(offset + 501));
  3845.  
  3846.     label(" Currency symbol pos.:");
  3847.     interpret(53, (ULONG) *(offset + 502));
  3848.  
  3849.     label("First day of the week:");
  3850.     interpret(54, (ULONG) *(offset + 503));
  3851. }
  3852.  
  3853. AGLOBAL void iff_init(void)
  3854. {   iff.raw = FALSE;
  3855.  
  3856.     NewList(&List1);
  3857.     NewList(&List2);
  3858. }
  3859.  
  3860. AGLOBAL void iff_die(void)
  3861. {   IOBuffer[19] = (UBYTE) iff.raw;
  3862. }
  3863.  
  3864. AGLOBAL void iff_config(void)
  3865. {   iff.raw = (ULONG) IOBuffer[19];
  3866. }
  3867.  
  3868. AGLOBAL ULONG Hook6Func(struct Hook *h, VOID *o, VOID *msg)
  3869. {   /* "When the hook is called, the data argument points to the 
  3870.     window object and message argument to the IntuiMessage." */
  3871.  
  3872.     UWORD code, qual;
  3873.     ULONG scroll = 0;
  3874.  
  3875.     geta4(); // wait till here before doing anything
  3876.  
  3877.     code = ((struct IntuiMessage *) msg)->Code;
  3878.     qual = ((struct IntuiMessage *) msg)->Qualifier;
  3879.  
  3880.     switch(code)
  3881.     {
  3882.     case SCAN_HELP:
  3883.         helpabout();
  3884.     break;
  3885.     case SCAN_ESCAPE:
  3886.         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3887.         {   cleanexit(EXIT_SUCCESS);
  3888.         } else page = 0;
  3889.     break;
  3890.     case SCAN_UP:
  3891.         if (qual & IEQUALIFIER_CONTROL)
  3892.         {   scroll = LBP_TOP;
  3893.         } elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
  3894.         {   scroll = LBP_PAGEUP;
  3895.         } else scroll = LBP_LINEUP;
  3896.     break;
  3897.     case SCAN_DOWN:
  3898.         if (qual & IEQUALIFIER_CONTROL)
  3899.         {   scroll = LBP_BOTTOM;
  3900.         } elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
  3901.         {   scroll = LBP_PAGEDOWN;
  3902.         } else scroll = LBP_LINEDOWN;
  3903.     break;
  3904.     case SCAN_PERIOD:
  3905.         if (asl("~(#?.info)"))
  3906.         {   strcpy(iff.pathname, aslresult);
  3907.  
  3908.             SetGadgetAttrs
  3909.             (   iff_gadgets[GID_6_ST6], MainWindowPtr, NULL,
  3910.                 STRINGA_TextVal, iff.pathname,
  3911.                 TAG_END
  3912.             ); // we don't know how many files in advance...
  3913.  
  3914.             readiff();
  3915.         }
  3916.     break;
  3917.     case SCAN_F:
  3918.         ActivateLayoutGadget(iff_gadgets[GID_6_LY1], MainWindowPtr, NULL, (Object) iff_gadgets[GID_6_ST1]);
  3919.     break;
  3920.     case SCAN_P:
  3921.         ActivateLayoutGadget(iff_gadgets[GID_6_LY1], MainWindowPtr, NULL, (Object) iff_gadgets[GID_6_ST6]);
  3922.     break;
  3923.     case SCAN_R:
  3924.         // the gadget is handled automatically by the system, all we need
  3925.         // to do is update our internal record of the state of the gadget
  3926.         if (!(GetAttr
  3927.         (   GA_Selected, iff_gadgets[GID_6_CB1], (ULONG *) &iff.raw
  3928.         )))
  3929.         {   rq("Unsupported inquiry!"); // should never happen
  3930.         }
  3931.         if (selectedchunk && known)
  3932.         {   tellchunk(selectedchunk);
  3933.         }
  3934.     break;
  3935.     default:
  3936.     break;
  3937.     }
  3938.  
  3939.     if (code == SCAN_UP || code == SCAN_DOWN)
  3940.     {   SetGadgetAttrs
  3941.         (   iff_gadgets[GID_6_LB2],       // pointer to gadget
  3942.             MainWindowPtr,                // pointer to window (not window object!)
  3943.             NULL,                         // pointer to requester
  3944.             LISTBROWSER_Position, scroll, // tags
  3945.             TAG_DONE                      // done
  3946.         );
  3947.     }
  3948.  
  3949.     return(1);
  3950. }
  3951.  
  3952. MODULE void label(STRPTR text)
  3953. {   ULONG i, length;
  3954.  
  3955.     length = strlen(text);
  3956.  
  3957.     strcpy(tempstring1, text);
  3958.     if (length < LABELLENGTH)
  3959.     {   for (i = length; i <= LABELLENGTH; i++)
  3960.         {   strcat(tempstring1, " ");
  3961. }   }   }
  3962.  
  3963. MODULE void dobool(UBYTE thebool)
  3964. {   if (thebool)
  3965.     {   strcat(tempstring1, "Yes");
  3966.     } else strcat(tempstring1, "No");
  3967.     addreactionnode(&List2, tempstring1);
  3968. }
  3969.  
  3970. MODULE void snumcat(SLONG thenumber, ABOOL finished)
  3971. {   stcl_d(tempstring2, thenumber);
  3972.     strcat(tempstring1, tempstring2);
  3973.  
  3974.     if (finished)
  3975.     {   addreactionnode(&List2, tempstring1);
  3976. }   }
  3977.  
  3978. MODULE void unumcat(ULONG thenumber, ABOOL finished)
  3979. {   stcul_d(tempstring2, thenumber);
  3980.     strcat(tempstring1, tempstring2);
  3981.  
  3982.     if (finished)
  3983.     {   addreactionnode(&List2, tempstring1);
  3984. }   }
  3985.  
  3986. MODULE void interpret(ULONG tablenum, ULONG value)
  3987. {   snumcat((SLONG) value, FALSE);
  3988.     strcat(tempstring1, " (");
  3989.  
  3990.     if (value > table[tablenum].entries)
  3991.     {   strcat(tempstring1, "?");
  3992.     } else
  3993.     {   strcat(tempstring1, table[tablenum].tablestring[value]);
  3994.     }
  3995.  
  3996.     strcat(tempstring1, ")");
  3997.     addreactionnode(&List2, tempstring1);
  3998. }
  3999.